Advertisement
Guest User

Untitled

a guest
Aug 19th, 2016
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 336.67 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. #include "scriptmanager.h"
  39. #include "store.h"
  40.  
  41. extern Chat* g_chat;
  42. extern Game g_game;
  43. extern Monsters g_monsters;
  44. extern ConfigManager g_config;
  45. extern Vocations g_vocations;
  46. extern Spells* g_spells;
  47. extern Store* g_store;
  48.  
  49. enum {
  50. EVENT_ID_LOADING = 1,
  51. EVENT_ID_USER = 1000,
  52. };
  53.  
  54. ScriptEnvironment::DBResultMap ScriptEnvironment::m_tempResults;
  55. uint32_t ScriptEnvironment::m_lastResultId = 0;
  56.  
  57. std::multimap<ScriptEnvironment*, Item*> ScriptEnvironment::tempItems;
  58.  
  59. LuaEnvironment g_luaEnvironment;
  60.  
  61. ScriptEnvironment::ScriptEnvironment()
  62. {
  63. m_curNpc = nullptr;
  64. resetEnv();
  65. m_lastUID = std::numeric_limits<uint16_t>::max();
  66. }
  67.  
  68. ScriptEnvironment::~ScriptEnvironment()
  69. {
  70. resetEnv();
  71. }
  72.  
  73. void ScriptEnvironment::resetEnv()
  74. {
  75. m_scriptId = 0;
  76. m_callbackId = 0;
  77. m_timerEvent = false;
  78. m_interface = nullptr;
  79. localMap.clear();
  80. m_tempResults.clear();
  81.  
  82. auto pair = tempItems.equal_range(this);
  83. auto it = pair.first;
  84. while (it != pair.second) {
  85. Item* item = it->second;
  86. if (item->getParent() == VirtualCylinder::virtualCylinder) {
  87. g_game.ReleaseItem(item);
  88. }
  89. it = tempItems.erase(it);
  90. }
  91. }
  92.  
  93. bool ScriptEnvironment::setCallbackId(int32_t callbackId, LuaScriptInterface* scriptInterface)
  94. {
  95. if (m_callbackId != 0) {
  96. //nested callbacks are not allowed
  97. if (m_interface) {
  98. m_interface->reportErrorFunc("Nested callbacks!");
  99. }
  100. return false;
  101. }
  102.  
  103. m_callbackId = callbackId;
  104. m_interface = scriptInterface;
  105. return true;
  106. }
  107.  
  108. void ScriptEnvironment::getEventInfo(int32_t& scriptId, std::string& desc, LuaScriptInterface*& scriptInterface, int32_t& callbackId, bool& timerEvent) const
  109. {
  110. scriptId = m_scriptId;
  111. desc = m_eventdesc;
  112. scriptInterface = m_interface;
  113. callbackId = m_callbackId;
  114. timerEvent = m_timerEvent;
  115. }
  116.  
  117. uint32_t ScriptEnvironment::addThing(Thing* thing)
  118. {
  119. if (!thing || thing->isRemoved()) {
  120. return 0;
  121. }
  122.  
  123. Creature* creature = thing->getCreature();
  124. if (creature) {
  125. return creature->getID();
  126. }
  127.  
  128. Item* item = thing->getItem();
  129. if (item && item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) {
  130. return item->getUniqueId();
  131. }
  132.  
  133. for (const auto& it : localMap) {
  134. if (it.second == item) {
  135. return it.first;
  136. }
  137. }
  138.  
  139. localMap[++m_lastUID] = item;
  140. return m_lastUID;
  141. }
  142.  
  143. void ScriptEnvironment::insertItem(uint32_t uid, Item* item)
  144. {
  145. auto result = localMap.emplace(uid, item);
  146. if (!result.second) {
  147. std::cout << std::endl << "Lua Script Error: Thing uid already taken.";
  148. }
  149. }
  150.  
  151. Thing* ScriptEnvironment::getThingByUID(uint32_t uid)
  152. {
  153. if (uid >= 0x10000000) {
  154. return g_game.getCreatureByID(uid);
  155. }
  156.  
  157. if (uid <= std::numeric_limits<uint16_t>::max()) {
  158. Item* item = g_game.getUniqueItem(uid);
  159. if (item && !item->isRemoved()) {
  160. return item;
  161. }
  162. return nullptr;
  163. }
  164.  
  165. auto it = localMap.find(uid);
  166. if (it != localMap.end()) {
  167. Item* item = it->second;
  168. if (!item->isRemoved()) {
  169. return item;
  170. }
  171. }
  172. return nullptr;
  173. }
  174.  
  175. Item* ScriptEnvironment::getItemByUID(uint32_t uid)
  176. {
  177. Thing* thing = getThingByUID(uid);
  178. if (!thing) {
  179. return nullptr;
  180. }
  181. return thing->getItem();
  182. }
  183.  
  184. Container* ScriptEnvironment::getContainerByUID(uint32_t uid)
  185. {
  186. Item* item = getItemByUID(uid);
  187. if (!item) {
  188. return nullptr;
  189. }
  190. return item->getContainer();
  191. }
  192.  
  193. void ScriptEnvironment::removeItemByUID(uint32_t uid)
  194. {
  195. if (uid <= std::numeric_limits<uint16_t>::max()) {
  196. g_game.removeUniqueItem(uid);
  197. return;
  198. }
  199.  
  200. auto it = localMap.find(uid);
  201. if (it != localMap.end()) {
  202. localMap.erase(it);
  203. }
  204. }
  205.  
  206. void ScriptEnvironment::addTempItem(Item* item)
  207. {
  208. tempItems.emplace(this, item);
  209. }
  210.  
  211. void ScriptEnvironment::removeTempItem(Item* item)
  212. {
  213. for (auto it = tempItems.begin(), end = tempItems.end(); it != end; ++it) {
  214. if (it->second == item) {
  215. tempItems.erase(it);
  216. break;
  217. }
  218. }
  219. }
  220.  
  221. uint32_t ScriptEnvironment::addResult(DBResult_ptr res)
  222. {
  223. m_tempResults[++m_lastResultId] = res;
  224. return m_lastResultId;
  225. }
  226.  
  227. bool ScriptEnvironment::removeResult(uint32_t id)
  228. {
  229. auto it = m_tempResults.find(id);
  230. if (it == m_tempResults.end()) {
  231. return false;
  232. }
  233.  
  234. m_tempResults.erase(it);
  235. return true;
  236. }
  237.  
  238. DBResult_ptr ScriptEnvironment::getResultByID(uint32_t id)
  239. {
  240. auto it = m_tempResults.find(id);
  241. if (it == m_tempResults.end()) {
  242. return nullptr;
  243. }
  244. return it->second;
  245. }
  246.  
  247. std::string LuaScriptInterface::getErrorDesc(ErrorCode_t code)
  248. {
  249. switch (code) {
  250. case LUA_ERROR_PLAYER_NOT_FOUND: return "Player not found";
  251. case LUA_ERROR_CREATURE_NOT_FOUND: return "Creature not found";
  252. case LUA_ERROR_ITEM_NOT_FOUND: return "Item not found";
  253. case LUA_ERROR_THING_NOT_FOUND: return "Thing not found";
  254. case LUA_ERROR_TILE_NOT_FOUND: return "Tile not found";
  255. case LUA_ERROR_HOUSE_NOT_FOUND: return "House not found";
  256. case LUA_ERROR_COMBAT_NOT_FOUND: return "Combat not found";
  257. case LUA_ERROR_CONDITION_NOT_FOUND: return "Condition not found";
  258. case LUA_ERROR_AREA_NOT_FOUND: return "Area not found";
  259. case LUA_ERROR_CONTAINER_NOT_FOUND: return "Container not found";
  260. case LUA_ERROR_VARIANT_NOT_FOUND: return "Variant not found";
  261. case LUA_ERROR_VARIANT_UNKNOWN: return "Unknown variant type";
  262. case LUA_ERROR_SPELL_NOT_FOUND: return "Spell not found";
  263. default: return "Bad error code";
  264. }
  265. }
  266.  
  267. ScriptEnvironment LuaScriptInterface::m_scriptEnv[16];
  268. int32_t LuaScriptInterface::m_scriptEnvIndex = -1;
  269.  
  270. LuaScriptInterface::LuaScriptInterface(std::string interfaceName)
  271. : m_luaState(nullptr), m_interfaceName(interfaceName), m_eventTableRef(-1), m_runningEventId(EVENT_ID_USER)
  272. {
  273. if (!g_luaEnvironment.getLuaState()) {
  274. g_luaEnvironment.initState();
  275. }
  276. }
  277.  
  278. LuaScriptInterface::~LuaScriptInterface()
  279. {
  280. closeState();
  281. }
  282.  
  283. bool LuaScriptInterface::reInitState()
  284. {
  285. g_luaEnvironment.clearCombatObjects(this);
  286. g_luaEnvironment.clearAreaObjects(this);
  287.  
  288. closeState();
  289. return initState();
  290. }
  291.  
  292. /// Same as lua_pcall, but adds stack trace to error strings in called function.
  293. int LuaScriptInterface::protectedCall(lua_State* L, int nargs, int nresults)
  294. {
  295. int error_index = lua_gettop(L) - nargs;
  296. lua_pushcfunction(L, luaErrorHandler);
  297. lua_insert(L, error_index);
  298.  
  299. int ret = lua_pcall(L, nargs, nresults, error_index);
  300. lua_remove(L, error_index);
  301. return ret;
  302. }
  303.  
  304. int32_t LuaScriptInterface::loadFile(const std::string& file, Npc* npc /* = nullptr*/)
  305. {
  306. //loads file as a chunk at stack top
  307. int ret = luaL_loadfile(m_luaState, file.c_str());
  308. if (ret != 0) {
  309. m_lastLuaError = popString(m_luaState);
  310. return -1;
  311. }
  312.  
  313. //check that it is loaded as a function
  314. if (!isFunction(m_luaState, -1)) {
  315. return -1;
  316. }
  317.  
  318. m_loadingFile = file;
  319.  
  320. if (!reserveScriptEnv()) {
  321. return -1;
  322. }
  323.  
  324. ScriptEnvironment* env = getScriptEnv();
  325. env->setScriptId(EVENT_ID_LOADING, this);
  326. env->setNpc(npc);
  327.  
  328. //execute it
  329. ret = protectedCall(m_luaState, 0, 0);
  330. if (ret != 0) {
  331. reportError(nullptr, popString(m_luaState));
  332. resetScriptEnv();
  333. return -1;
  334. }
  335.  
  336. resetScriptEnv();
  337. return 0;
  338. }
  339.  
  340. int32_t LuaScriptInterface::getEvent(const std::string& eventName)
  341. {
  342. //get our events table
  343. lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, m_eventTableRef);
  344. if (!isTable(m_luaState, -1)) {
  345. lua_pop(m_luaState, 1);
  346. return -1;
  347. }
  348.  
  349. //get current event function pointer
  350. lua_getglobal(m_luaState, eventName.c_str());
  351. if (!isFunction(m_luaState, -1)) {
  352. lua_pop(m_luaState, 2);
  353. return -1;
  354. }
  355.  
  356. //save in our events table
  357. lua_pushvalue(m_luaState, -1);
  358. lua_rawseti(m_luaState, -3, m_runningEventId);
  359. lua_pop(m_luaState, 2);
  360.  
  361. //reset global value of this event
  362. lua_pushnil(m_luaState);
  363. lua_setglobal(m_luaState, eventName.c_str());
  364.  
  365. m_cacheFiles[m_runningEventId] = m_loadingFile + ":" + eventName;
  366. return m_runningEventId++;
  367. }
  368.  
  369. int32_t LuaScriptInterface::getMetaEvent(const std::string& globalName, const std::string& eventName)
  370. {
  371. //get our events table
  372. lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, m_eventTableRef);
  373. if (!isTable(m_luaState, -1)) {
  374. lua_pop(m_luaState, 1);
  375. return -1;
  376. }
  377.  
  378. //get current event function pointer
  379. lua_getglobal(m_luaState, globalName.c_str());
  380. lua_getfield(m_luaState, -1, eventName.c_str());
  381. if (!isFunction(m_luaState, -1)) {
  382. lua_pop(m_luaState, 3);
  383. return -1;
  384. }
  385.  
  386. //save in our events table
  387. lua_pushvalue(m_luaState, -1);
  388. lua_rawseti(m_luaState, -4, m_runningEventId);
  389. lua_pop(m_luaState, 1);
  390.  
  391. //reset global value of this event
  392. lua_pushnil(m_luaState);
  393. lua_setfield(m_luaState, -2, eventName.c_str());
  394. lua_pop(m_luaState, 2);
  395.  
  396. m_cacheFiles[m_runningEventId] = m_loadingFile + ":" + globalName + "@" + eventName;
  397. return m_runningEventId++;
  398. }
  399.  
  400. const std::string& LuaScriptInterface::getFileById(int32_t scriptId)
  401. {
  402. if (scriptId == EVENT_ID_LOADING) {
  403. return m_loadingFile;
  404. }
  405.  
  406. auto it = m_cacheFiles.find(scriptId);
  407. if (it == m_cacheFiles.end()) {
  408. static const std::string& unk = "(Unknown scriptfile)";
  409. return unk;
  410. }
  411. return it->second;
  412. }
  413.  
  414. std::string LuaScriptInterface::getStackTrace(const std::string& error_desc)
  415. {
  416. lua_getglobal(m_luaState, "debug");
  417. if (!isTable(m_luaState, -1)) {
  418. lua_pop(m_luaState, 1);
  419. return error_desc;
  420. }
  421.  
  422. lua_getfield(m_luaState, -1, "traceback");
  423. if (!isFunction(m_luaState, -1)) {
  424. lua_pop(m_luaState, 2);
  425. return error_desc;
  426. }
  427.  
  428. lua_replace(m_luaState, -2);
  429. pushString(m_luaState, error_desc);
  430. lua_call(m_luaState, 1, 1);
  431. return popString(m_luaState);
  432. }
  433.  
  434. void LuaScriptInterface::reportError(const char* function, const std::string& error_desc, bool stack_trace/* = false*/)
  435. {
  436. int32_t scriptId;
  437. int32_t callbackId;
  438. bool timerEvent;
  439. std::string event_desc;
  440. LuaScriptInterface* scriptInterface;
  441. getScriptEnv()->getEventInfo(scriptId, event_desc, scriptInterface, callbackId, timerEvent);
  442.  
  443. std::cout << std::endl << "Lua Script Error: ";
  444.  
  445. if (scriptInterface) {
  446. std::cout << '[' << scriptInterface->getInterfaceName() << "] " << std::endl;
  447.  
  448. if (timerEvent) {
  449. std::cout << "in a timer event called from: " << std::endl;
  450. }
  451.  
  452. if (callbackId) {
  453. std::cout << "in callback: " << scriptInterface->getFileById(callbackId) << std::endl;
  454. }
  455.  
  456. std::cout << scriptInterface->getFileById(scriptId) << std::endl;
  457. }
  458.  
  459. if (!event_desc.empty()) {
  460. std::cout << "Event: " << event_desc << std::endl;
  461. }
  462.  
  463. if (function) {
  464. std::cout << function << "(). ";
  465. }
  466.  
  467. if (stack_trace && scriptInterface) {
  468. std::cout << scriptInterface->getStackTrace(error_desc) << std::endl;
  469. } else {
  470. std::cout << error_desc << std::endl;
  471. }
  472. }
  473.  
  474. bool LuaScriptInterface::pushFunction(int32_t functionId)
  475. {
  476. lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, m_eventTableRef);
  477. if (!isTable(m_luaState, -1)) {
  478. return false;
  479. }
  480.  
  481. lua_rawgeti(m_luaState, -1, functionId);
  482. lua_replace(m_luaState, -2);
  483. return isFunction(m_luaState, -1);
  484. }
  485.  
  486. bool LuaScriptInterface::initState()
  487. {
  488. m_luaState = g_luaEnvironment.getLuaState();
  489. if (!m_luaState) {
  490. return false;
  491. }
  492.  
  493. lua_newtable(m_luaState);
  494. m_eventTableRef = luaL_ref(m_luaState, LUA_REGISTRYINDEX);
  495. m_runningEventId = EVENT_ID_USER;
  496. return true;
  497. }
  498.  
  499. bool LuaScriptInterface::closeState()
  500. {
  501. if (!g_luaEnvironment.getLuaState() || !m_luaState) {
  502. return false;
  503. }
  504.  
  505. m_cacheFiles.clear();
  506. if (m_eventTableRef != -1) {
  507. luaL_unref(m_luaState, LUA_REGISTRYINDEX, m_eventTableRef);
  508. m_eventTableRef = -1;
  509. }
  510.  
  511. m_luaState = nullptr;
  512. return true;
  513. }
  514.  
  515. int LuaScriptInterface::luaErrorHandler(lua_State* L)
  516. {
  517. const std::string& errorMessage = popString(L);
  518. auto interface = getScriptEnv()->getScriptInterface();
  519. assert(interface); //This fires if the ScriptEnvironment hasn't been setup
  520. pushString(L, interface->getStackTrace(errorMessage));
  521. return 1;
  522. }
  523.  
  524. bool LuaScriptInterface::callFunction(int params)
  525. {
  526. bool result = false;
  527. int size = lua_gettop(m_luaState);
  528. if (protectedCall(m_luaState, params, 1) != 0) {
  529. LuaScriptInterface::reportError(nullptr, LuaScriptInterface::getString(m_luaState, -1));
  530. } else {
  531. result = LuaScriptInterface::getBoolean(m_luaState, -1);
  532. }
  533.  
  534. lua_pop(m_luaState, 1);
  535. if ((lua_gettop(m_luaState) + params + 1) != size) {
  536. LuaScriptInterface::reportError(nullptr, "Stack size changed!");
  537. }
  538.  
  539. resetScriptEnv();
  540. return result;
  541. }
  542.  
  543. void LuaScriptInterface::callVoidFunction(int params)
  544. {
  545. int size = lua_gettop(m_luaState);
  546. if (protectedCall(m_luaState, params, 0) != 0) {
  547. LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(m_luaState));
  548. }
  549.  
  550. if ((lua_gettop(m_luaState) + params + 1) != size) {
  551. LuaScriptInterface::reportError(nullptr, "Stack size changed!");
  552. }
  553.  
  554. resetScriptEnv();
  555. }
  556.  
  557. void LuaScriptInterface::pushVariant(lua_State* L, const LuaVariant& var)
  558. {
  559. lua_createtable(L, 0, 2);
  560. setField(L, "type", var.type);
  561. switch (var.type) {
  562. case VARIANT_NUMBER:
  563. setField(L, "number", var.number);
  564. break;
  565. case VARIANT_STRING:
  566. setField(L, "string", var.text);
  567. break;
  568. case VARIANT_TARGETPOSITION:
  569. case VARIANT_POSITION: {
  570. pushPosition(L, var.pos);
  571. lua_setfield(L, -2, "pos");
  572. break;
  573. }
  574. default:
  575. break;
  576. }
  577. setMetatable(L, -1, "Variant");
  578. }
  579.  
  580. void LuaScriptInterface::pushThing(lua_State* L, Thing* thing)
  581. {
  582. if (!thing) {
  583. lua_createtable(L, 0, 4);
  584. setField(L, "uid", 0);
  585. setField(L, "itemid", 0);
  586. setField(L, "actionid", 0);
  587. setField(L, "type", 0);
  588. return;
  589. }
  590.  
  591. if (Item* item = thing->getItem()) {
  592. pushUserdata<Item>(L, item);
  593. setItemMetatable(L, -1, item);
  594. } else if (Creature* creature = thing->getCreature()) {
  595. pushUserdata<Creature>(L, creature);
  596. setCreatureMetatable(L, -1, creature);
  597. } else {
  598. lua_pushnil(L);
  599. }
  600. }
  601.  
  602. void LuaScriptInterface::pushCylinder(lua_State* L, Cylinder* cylinder)
  603. {
  604. if (Creature* creature = cylinder->getCreature()) {
  605. pushUserdata<Creature>(L, creature);
  606. setCreatureMetatable(L, -1, creature);
  607. } else if (Item* parentItem = cylinder->getItem()) {
  608. pushUserdata<Item>(L, parentItem);
  609. setItemMetatable(L, -1, parentItem);
  610. } else if (Tile* tile = cylinder->getTile()) {
  611. pushUserdata<Tile>(L, tile);
  612. setMetatable(L, -1, "Tile");
  613. } else if (cylinder == VirtualCylinder::virtualCylinder) {
  614. pushBoolean(L, true);
  615. } else {
  616. lua_pushnil(L);
  617. }
  618. }
  619.  
  620. void LuaScriptInterface::pushString(lua_State* L, const std::string& value)
  621. {
  622. lua_pushlstring(L, value.c_str(), value.length());
  623. }
  624.  
  625. void LuaScriptInterface::pushCallback(lua_State* L, int32_t callback)
  626. {
  627. lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
  628. }
  629.  
  630. std::string LuaScriptInterface::popString(lua_State* L)
  631. {
  632. if (lua_gettop(L) == 0) {
  633. return std::string();
  634. }
  635.  
  636. std::string str(getString(L, -1));
  637. lua_pop(L, 1);
  638. return str;
  639. }
  640.  
  641. int32_t LuaScriptInterface::popCallback(lua_State* L)
  642. {
  643. return luaL_ref(L, LUA_REGISTRYINDEX);
  644. }
  645.  
  646. // Metatables
  647. void LuaScriptInterface::setMetatable(lua_State* L, int32_t index, const std::string& name)
  648. {
  649. luaL_getmetatable(L, name.c_str());
  650. lua_setmetatable(L, index - 1);
  651. }
  652.  
  653. void LuaScriptInterface::setWeakMetatable(lua_State* L, int32_t index, const std::string& name)
  654. {
  655. static std::set<std::string> weakObjectTypes;
  656. const std::string& weakName = name + "_weak";
  657.  
  658. auto result = weakObjectTypes.emplace(name);
  659. if (result.second) {
  660. luaL_getmetatable(L, name.c_str());
  661. int childMetatable = lua_gettop(L);
  662.  
  663. luaL_newmetatable(L, weakName.c_str());
  664. int metatable = lua_gettop(L);
  665.  
  666. static const std::vector<std::string> methodKeys = {"__index", "__metatable", "__eq"};
  667. for (const std::string& metaKey : methodKeys) {
  668. lua_getfield(L, childMetatable, metaKey.c_str());
  669. lua_setfield(L, metatable, metaKey.c_str());
  670. }
  671.  
  672. static const std::vector<int> methodIndexes = {'h', 'p', 't'};
  673. for (int metaIndex : methodIndexes) {
  674. lua_rawgeti(L, childMetatable, metaIndex);
  675. lua_rawseti(L, metatable, metaIndex);
  676. }
  677.  
  678. lua_pushnil(L);
  679. lua_setfield(L, metatable, "__gc");
  680.  
  681. lua_remove(L, childMetatable);
  682. } else {
  683. luaL_getmetatable(L, weakName.c_str());
  684. }
  685. lua_setmetatable(L, index - 1);
  686. }
  687.  
  688. void LuaScriptInterface::setItemMetatable(lua_State* L, int32_t index, const Item* item)
  689. {
  690. if (item->getContainer()) {
  691. luaL_getmetatable(L, "Container");
  692. } else if (item->getTeleport()) {
  693. luaL_getmetatable(L, "Teleport");
  694. } else {
  695. luaL_getmetatable(L, "Item");
  696. }
  697. lua_setmetatable(L, index - 1);
  698. }
  699.  
  700. void LuaScriptInterface::setCreatureMetatable(lua_State* L, int32_t index, const Creature* creature)
  701. {
  702. if (creature->getPlayer()) {
  703. luaL_getmetatable(L, "Player");
  704. } else if (creature->getMonster()) {
  705. luaL_getmetatable(L, "Monster");
  706. } else {
  707. luaL_getmetatable(L, "Npc");
  708. }
  709. lua_setmetatable(L, index - 1);
  710. }
  711.  
  712. // Get
  713. std::string LuaScriptInterface::getString(lua_State* L, int32_t arg)
  714. {
  715. size_t len;
  716. const char* c_str = lua_tolstring(L, arg, &len);
  717. if (!c_str || len == 0) {
  718. return std::string();
  719. }
  720. return std::string(c_str, len);
  721. }
  722.  
  723. Position LuaScriptInterface::getPosition(lua_State* L, int32_t arg, int32_t& stackpos)
  724. {
  725. Position position;
  726. position.x = getField<uint16_t>(L, arg, "x");
  727. position.y = getField<uint16_t>(L, arg, "y");
  728. position.z = getField<uint8_t>(L, arg, "z");
  729.  
  730. lua_getfield(L, arg, "stackpos");
  731. if (lua_isnil(L, -1) == 1) {
  732. stackpos = 0;
  733. } else {
  734. stackpos = getNumber<int32_t>(L, -1);
  735. }
  736.  
  737. lua_pop(L, 4);
  738. return position;
  739. }
  740.  
  741. Position LuaScriptInterface::getPosition(lua_State* L, int32_t arg)
  742. {
  743. Position position;
  744. position.x = getField<uint16_t>(L, arg, "x");
  745. position.y = getField<uint16_t>(L, arg, "y");
  746. position.z = getField<uint8_t>(L, arg, "z");
  747.  
  748. lua_pop(L, 3);
  749. return position;
  750. }
  751.  
  752. Outfit_t LuaScriptInterface::getOutfit(lua_State* L, int32_t arg)
  753. {
  754. Outfit_t outfit;
  755. outfit.lookMount = getField<uint16_t>(L, arg, "lookMount");
  756. outfit.lookAddons = getField<uint8_t>(L, arg, "lookAddons");
  757.  
  758. outfit.lookFeet = getField<uint8_t>(L, arg, "lookFeet");
  759. outfit.lookLegs = getField<uint8_t>(L, arg, "lookLegs");
  760. outfit.lookBody = getField<uint8_t>(L, arg, "lookBody");
  761. outfit.lookHead = getField<uint8_t>(L, arg, "lookHead");
  762.  
  763. outfit.lookTypeEx = getField<uint16_t>(L, arg, "lookTypeEx");
  764. outfit.lookType = getField<uint16_t>(L, arg, "lookType");
  765.  
  766. lua_pop(L, 8);
  767. return outfit;
  768. }
  769.  
  770. LuaVariant LuaScriptInterface::getVariant(lua_State* L, int32_t arg)
  771. {
  772. LuaVariant var;
  773. switch (var.type = getField<LuaVariantType_t>(L, arg, "type")) {
  774. case VARIANT_NUMBER: {
  775. var.number = getField<uint32_t>(L, arg, "number");
  776. lua_pop(L, 2);
  777. break;
  778. }
  779.  
  780. case VARIANT_STRING: {
  781. var.text = getFieldString(L, arg, "string");
  782. lua_pop(L, 2);
  783. break;
  784. }
  785.  
  786. case VARIANT_POSITION:
  787. case VARIANT_TARGETPOSITION: {
  788. lua_getfield(L, arg, "pos");
  789. var.pos = getPosition(L, lua_gettop(L));
  790. lua_pop(L, 2);
  791. break;
  792. }
  793.  
  794. default: {
  795. var.type = VARIANT_NONE;
  796. lua_pop(L, 1);
  797. break;
  798. }
  799. }
  800. return var;
  801. }
  802.  
  803. Thing* LuaScriptInterface::getThing(lua_State* L, int32_t arg)
  804. {
  805. Thing* thing;
  806. if (lua_getmetatable(L, arg) != 0) {
  807. lua_rawgeti(L, -1, 't');
  808. switch(getNumber<uint32_t>(L, -1)) {
  809. case LuaData_Item:
  810. thing = getUserdata<Item>(L, arg);
  811. break;
  812. case LuaData_Container:
  813. thing = getUserdata<Container>(L, arg);
  814. break;
  815. case LuaData_Teleport:
  816. thing = getUserdata<Teleport>(L, arg);
  817. break;
  818. case LuaData_Player:
  819. thing = getUserdata<Player>(L, arg);
  820. break;
  821. case LuaData_Monster:
  822. thing = getUserdata<Monster>(L, arg);
  823. break;
  824. case LuaData_Npc:
  825. thing = getUserdata<Npc>(L, arg);
  826. break;
  827. default:
  828. thing = nullptr;
  829. break;
  830. }
  831. lua_pop(L, 2);
  832. } else {
  833. thing = getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, arg));
  834. }
  835. return thing;
  836. }
  837.  
  838. Creature* LuaScriptInterface::getCreature(lua_State* L, int32_t arg)
  839. {
  840. if (isUserdata(L, arg)) {
  841. return getUserdata<Creature>(L, arg);
  842. }
  843. return g_game.getCreatureByID(getNumber<uint32_t>(L, arg));
  844. }
  845.  
  846. Player* LuaScriptInterface::getPlayer(lua_State* L, int32_t arg)
  847. {
  848. if (isUserdata(L, arg)) {
  849. return getUserdata<Player>(L, arg);
  850. }
  851. return g_game.getPlayerByID(getNumber<uint32_t>(L, arg));
  852. }
  853.  
  854. std::string LuaScriptInterface::getFieldString(lua_State* L, int32_t arg, const std::string& key)
  855. {
  856. lua_getfield(L, arg, key.c_str());
  857. return getString(L, -1);
  858. }
  859.  
  860. LuaDataType LuaScriptInterface::getUserdataType(lua_State* L, int32_t arg)
  861. {
  862. if (lua_getmetatable(L, arg) == 0) {
  863. return LuaData_Unknown;
  864. }
  865. lua_rawgeti(L, -1, 't');
  866.  
  867. LuaDataType type = getNumber<LuaDataType>(L, -1);
  868. lua_pop(L, 2);
  869.  
  870. return type;
  871. }
  872.  
  873. // Push
  874. void LuaScriptInterface::pushBoolean(lua_State* L, bool value)
  875. {
  876. lua_pushboolean(L, value ? 1 : 0);
  877. }
  878.  
  879. void LuaScriptInterface::pushPosition(lua_State* L, const Position& position, int32_t stackpos/* = 0*/)
  880. {
  881. lua_createtable(L, 0, 4);
  882.  
  883. setField(L, "x", position.x);
  884. setField(L, "y", position.y);
  885. setField(L, "z", position.z);
  886. setField(L, "stackpos", stackpos);
  887.  
  888. setMetatable(L, -1, "Position");
  889. }
  890.  
  891. void LuaScriptInterface::pushOutfit(lua_State* L, const Outfit_t& outfit)
  892. {
  893. lua_createtable(L, 0, 8);
  894. setField(L, "lookType", outfit.lookType);
  895. setField(L, "lookTypeEx", outfit.lookTypeEx);
  896. setField(L, "lookHead", outfit.lookHead);
  897. setField(L, "lookBody", outfit.lookBody);
  898. setField(L, "lookLegs", outfit.lookLegs);
  899. setField(L, "lookFeet", outfit.lookFeet);
  900. setField(L, "lookAddons", outfit.lookAddons);
  901. setField(L, "lookMount", outfit.lookMount);
  902. }
  903.  
  904. #define registerEnum(value) { std::string enumName = #value; registerGlobalVariable(enumName.substr(enumName.find_last_of(':') + 1), value); }
  905. #define registerEnumIn(tableName, value) { std::string enumName = #value; registerVariable(tableName, enumName.substr(enumName.find_last_of(':') + 1), value); }
  906.  
  907. void LuaScriptInterface::registerFunctions()
  908. {
  909. //getPlayerFlagValue(cid, flag)
  910. lua_register(m_luaState, "getPlayerFlagValue", LuaScriptInterface::luaGetPlayerFlagValue);
  911.  
  912. //getPlayerInstantSpellCount(cid)
  913. lua_register(m_luaState, "getPlayerInstantSpellCount", LuaScriptInterface::luaGetPlayerInstantSpellCount);
  914.  
  915. //getPlayerInstantSpellInfo(cid, index)
  916. lua_register(m_luaState, "getPlayerInstantSpellInfo", LuaScriptInterface::luaGetPlayerInstantSpellInfo);
  917.  
  918. //doPlayerAddItem(uid, itemid, <optional: default: 1> count/subtype)
  919. //doPlayerAddItem(cid, itemid, <optional: default: 1> count, <optional: default: 1> canDropOnMap, <optional: default: 1>subtype)
  920. //Returns uid of the created item
  921. lua_register(m_luaState, "doPlayerAddItem", LuaScriptInterface::luaDoPlayerAddItem);
  922.  
  923. //doCreateItem(itemid, type/count, pos)
  924. //Returns uid of the created item, only works on tiles.
  925. lua_register(m_luaState, "doCreateItem", LuaScriptInterface::luaDoCreateItem);
  926.  
  927. //doCreateItemEx(itemid, <optional> count/subtype)
  928. lua_register(m_luaState, "doCreateItemEx", LuaScriptInterface::luaDoCreateItemEx);
  929.  
  930. //doTileAddItemEx(pos, uid)
  931. lua_register(m_luaState, "doTileAddItemEx", LuaScriptInterface::luaDoTileAddItemEx);
  932.  
  933. //doMoveCreature(cid, direction)
  934. lua_register(m_luaState, "doMoveCreature", LuaScriptInterface::luaDoMoveCreature);
  935.  
  936. //doSetCreatureLight(cid, lightLevel, lightColor, time)
  937. lua_register(m_luaState, "doSetCreatureLight", LuaScriptInterface::luaDoSetCreatureLight);
  938.  
  939. //getCreatureCondition(cid, condition[, subId])
  940. lua_register(m_luaState, "getCreatureCondition", LuaScriptInterface::luaGetCreatureCondition);
  941.  
  942. //isValidUID(uid)
  943. lua_register(m_luaState, "isValidUID", LuaScriptInterface::luaIsValidUID);
  944.  
  945. //isDepot(uid)
  946. lua_register(m_luaState, "isDepot", LuaScriptInterface::luaIsDepot);
  947.  
  948. //isMovable(uid)
  949. lua_register(m_luaState, "isMovable", LuaScriptInterface::luaIsMoveable);
  950.  
  951. //doAddContainerItem(uid, itemid, <optional> count/subtype)
  952. lua_register(m_luaState, "doAddContainerItem", LuaScriptInterface::luaDoAddContainerItem);
  953.  
  954. //getDepotId(uid)
  955. lua_register(m_luaState, "getDepotId", LuaScriptInterface::luaGetDepotId);
  956.  
  957. //getWorldTime()
  958. lua_register(m_luaState, "getWorldTime", LuaScriptInterface::luaGetWorldTime);
  959.  
  960. //getWorldLight()
  961. lua_register(m_luaState, "getWorldLight", LuaScriptInterface::luaGetWorldLight);
  962.  
  963. //getWorldUpTime()
  964. lua_register(m_luaState, "getWorldUpTime", LuaScriptInterface::luaGetWorldUpTime);
  965.  
  966. //createCombatArea( {area}, <optional> {extArea} )
  967. lua_register(m_luaState, "createCombatArea", LuaScriptInterface::luaCreateCombatArea);
  968.  
  969. //doAreaCombatHealth(cid, type, pos, area, min, max, effect)
  970. lua_register(m_luaState, "doAreaCombatHealth", LuaScriptInterface::luaDoAreaCombatHealth);
  971.  
  972. //doTargetCombatHealth(cid, target, type, min, max, effect)
  973. lua_register(m_luaState, "doTargetCombatHealth", LuaScriptInterface::luaDoTargetCombatHealth);
  974.  
  975. //doAreaCombatMana(cid, pos, area, min, max, effect)
  976. lua_register(m_luaState, "doAreaCombatMana", LuaScriptInterface::luaDoAreaCombatMana);
  977.  
  978. //doTargetCombatMana(cid, target, min, max, effect)
  979. lua_register(m_luaState, "doTargetCombatMana", LuaScriptInterface::luaDoTargetCombatMana);
  980.  
  981. //doAreaCombatCondition(cid, pos, area, condition, effect)
  982. lua_register(m_luaState, "doAreaCombatCondition", LuaScriptInterface::luaDoAreaCombatCondition);
  983.  
  984. //doTargetCombatCondition(cid, target, condition, effect)
  985. lua_register(m_luaState, "doTargetCombatCondition", LuaScriptInterface::luaDoTargetCombatCondition);
  986.  
  987. //doAreaCombatDispel(cid, pos, area, type, effect)
  988. lua_register(m_luaState, "doAreaCombatDispel", LuaScriptInterface::luaDoAreaCombatDispel);
  989.  
  990. //doTargetCombatDispel(cid, target, type, effect)
  991. lua_register(m_luaState, "doTargetCombatDispel", LuaScriptInterface::luaDoTargetCombatDispel);
  992.  
  993. //doChallengeCreature(cid, target)
  994. lua_register(m_luaState, "doChallengeCreature", LuaScriptInterface::luaDoChallengeCreature);
  995.  
  996. //doSetMonsterOutfit(cid, name, time)
  997. lua_register(m_luaState, "doSetMonsterOutfit", LuaScriptInterface::luaSetMonsterOutfit);
  998.  
  999. //doSetItemOutfit(cid, item, time)
  1000. lua_register(m_luaState, "doSetItemOutfit", LuaScriptInterface::luaSetItemOutfit);
  1001.  
  1002. //doSetCreatureOutfit(cid, outfit, time)
  1003. lua_register(m_luaState, "doSetCreatureOutfit", LuaScriptInterface::luaSetCreatureOutfit);
  1004.  
  1005. //isInArray(array, value)
  1006. lua_register(m_luaState, "isInArray", LuaScriptInterface::luaIsInArray);
  1007.  
  1008. //addEvent(callback, delay, ...)
  1009. lua_register(m_luaState, "addEvent", LuaScriptInterface::luaAddEvent);
  1010.  
  1011. //stopEvent(eventid)
  1012. lua_register(m_luaState, "stopEvent", LuaScriptInterface::luaStopEvent);
  1013.  
  1014. //saveServer()
  1015. lua_register(m_luaState, "saveServer", LuaScriptInterface::luaSaveServer);
  1016.  
  1017. //cleanMap()
  1018. lua_register(m_luaState, "cleanMap", LuaScriptInterface::luaCleanMap);
  1019.  
  1020. //debugPrint(text)
  1021. lua_register(m_luaState, "debugPrint", LuaScriptInterface::luaDebugPrint);
  1022.  
  1023. //isInWar(cid, target)
  1024. lua_register(m_luaState, "isInWar", LuaScriptInterface::luaIsInWar);
  1025.  
  1026. //getWaypointPosition(name)
  1027. lua_register(m_luaState, "getWaypointPositionByName", LuaScriptInterface::luaGetWaypointPositionByName);
  1028.  
  1029. //sendChannelMessage(channelId, type, message)
  1030. lua_register(m_luaState, "sendChannelMessage", LuaScriptInterface::luaSendChannelMessage);
  1031.  
  1032. //sendGuildChannelMessage(guildId, type, message)
  1033. lua_register(m_luaState, "sendGuildChannelMessage", LuaScriptInterface::luaSendGuildChannelMessage);
  1034.  
  1035. #ifndef LUAJIT_VERSION
  1036. //bit operations for Lua, based on bitlib project release 24
  1037. //bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift
  1038. luaL_register(m_luaState, "bit", LuaScriptInterface::luaBitReg);
  1039. #endif
  1040.  
  1041. //configManager table
  1042. luaL_register(m_luaState, "configManager", LuaScriptInterface::luaConfigManagerTable);
  1043.  
  1044. //db table
  1045. luaL_register(m_luaState, "db", LuaScriptInterface::luaDatabaseTable);
  1046.  
  1047. //result table
  1048. luaL_register(m_luaState, "result", LuaScriptInterface::luaResultTable);
  1049.  
  1050. /* New functions */
  1051. //registerClass(className, baseClass, newFunction)
  1052. //registerTable(tableName)
  1053. //registerMethod(className, functionName, function)
  1054. //registerMetaMethod(className, functionName, function)
  1055. //registerGlobalMethod(functionName, function)
  1056. //registerVariable(tableName, name, value)
  1057. //registerGlobalVariable(name, value)
  1058. //registerEnum(value)
  1059. //registerEnumIn(tableName, value)
  1060.  
  1061. // Enums
  1062. registerEnum(STORE_ERROR_PURCHASE)
  1063. registerEnum(STORE_ERROR_NETWORK)
  1064. registerEnum(STORE_ERROR_HISTORY)
  1065. registerEnum(STORE_ERROR_TRANSFER)
  1066. registerEnum(STORE_ERROR_INFORMATION)
  1067.  
  1068. registerEnum(ACCOUNT_TYPE_NORMAL)
  1069. registerEnum(ACCOUNT_TYPE_TUTOR)
  1070. registerEnum(ACCOUNT_TYPE_SENIORTUTOR)
  1071. registerEnum(ACCOUNT_TYPE_GAMEMASTER)
  1072. registerEnum(ACCOUNT_TYPE_GOD)
  1073.  
  1074. registerEnum(CALLBACK_PARAM_LEVELMAGICVALUE)
  1075. registerEnum(CALLBACK_PARAM_SKILLVALUE)
  1076. registerEnum(CALLBACK_PARAM_TARGETTILE)
  1077. registerEnum(CALLBACK_PARAM_TARGETCREATURE)
  1078.  
  1079. registerEnum(COMBAT_FORMULA_UNDEFINED)
  1080. registerEnum(COMBAT_FORMULA_LEVELMAGIC)
  1081. registerEnum(COMBAT_FORMULA_SKILL)
  1082. registerEnum(COMBAT_FORMULA_DAMAGE)
  1083.  
  1084. registerEnum(DIRECTION_NORTH)
  1085. registerEnum(DIRECTION_EAST)
  1086. registerEnum(DIRECTION_SOUTH)
  1087. registerEnum(DIRECTION_WEST)
  1088. registerEnum(DIRECTION_SOUTHWEST)
  1089. registerEnum(DIRECTION_SOUTHEAST)
  1090. registerEnum(DIRECTION_NORTHWEST)
  1091. registerEnum(DIRECTION_NORTHEAST)
  1092.  
  1093. registerEnum(COMBAT_NONE)
  1094. registerEnum(COMBAT_PHYSICALDAMAGE)
  1095. registerEnum(COMBAT_ENERGYDAMAGE)
  1096. registerEnum(COMBAT_EARTHDAMAGE)
  1097. registerEnum(COMBAT_FIREDAMAGE)
  1098. registerEnum(COMBAT_UNDEFINEDDAMAGE)
  1099. registerEnum(COMBAT_LIFEDRAIN)
  1100. registerEnum(COMBAT_MANADRAIN)
  1101. registerEnum(COMBAT_HEALING)
  1102. registerEnum(COMBAT_DROWNDAMAGE)
  1103. registerEnum(COMBAT_ICEDAMAGE)
  1104. registerEnum(COMBAT_HOLYDAMAGE)
  1105. registerEnum(COMBAT_DEATHDAMAGE)
  1106.  
  1107. registerEnum(COMBAT_PARAM_TYPE)
  1108. registerEnum(COMBAT_PARAM_EFFECT)
  1109. registerEnum(COMBAT_PARAM_DISTANCEEFFECT)
  1110. registerEnum(COMBAT_PARAM_BLOCKSHIELD)
  1111. registerEnum(COMBAT_PARAM_BLOCKARMOR)
  1112. registerEnum(COMBAT_PARAM_TARGETCASTERORTOPMOST)
  1113. registerEnum(COMBAT_PARAM_CREATEITEM)
  1114. registerEnum(COMBAT_PARAM_AGGRESSIVE)
  1115. registerEnum(COMBAT_PARAM_DISPEL)
  1116. registerEnum(COMBAT_PARAM_USECHARGES)
  1117.  
  1118. registerEnum(CONDITION_NONE)
  1119. registerEnum(CONDITION_POISON)
  1120. registerEnum(CONDITION_FIRE)
  1121. registerEnum(CONDITION_ENERGY)
  1122. registerEnum(CONDITION_BLEEDING)
  1123. registerEnum(CONDITION_HASTE)
  1124. registerEnum(CONDITION_PARALYZE)
  1125. registerEnum(CONDITION_OUTFIT)
  1126. registerEnum(CONDITION_INVISIBLE)
  1127. registerEnum(CONDITION_LIGHT)
  1128. registerEnum(CONDITION_MANASHIELD)
  1129. registerEnum(CONDITION_INFIGHT)
  1130. registerEnum(CONDITION_DRUNK)
  1131. registerEnum(CONDITION_EXHAUST_WEAPON)
  1132. registerEnum(CONDITION_REGENERATION)
  1133. registerEnum(CONDITION_SOUL)
  1134. registerEnum(CONDITION_DROWN)
  1135. registerEnum(CONDITION_MUTED)
  1136. registerEnum(CONDITION_CHANNELMUTEDTICKS)
  1137. registerEnum(CONDITION_YELLTICKS)
  1138. registerEnum(CONDITION_ATTRIBUTES)
  1139. registerEnum(CONDITION_FREEZING)
  1140. registerEnum(CONDITION_DAZZLED)
  1141. registerEnum(CONDITION_CURSED)
  1142. registerEnum(CONDITION_EXHAUST_COMBAT)
  1143. registerEnum(CONDITION_EXHAUST_HEAL)
  1144. registerEnum(CONDITION_PACIFIED)
  1145. registerEnum(CONDITION_SPELLCOOLDOWN)
  1146. registerEnum(CONDITION_SPELLGROUPCOOLDOWN)
  1147.  
  1148. registerEnum(CONDITIONID_DEFAULT)
  1149. registerEnum(CONDITIONID_COMBAT)
  1150. registerEnum(CONDITIONID_HEAD)
  1151. registerEnum(CONDITIONID_NECKLACE)
  1152. registerEnum(CONDITIONID_BACKPACK)
  1153. registerEnum(CONDITIONID_ARMOR)
  1154. registerEnum(CONDITIONID_RIGHT)
  1155. registerEnum(CONDITIONID_LEFT)
  1156. registerEnum(CONDITIONID_LEGS)
  1157. registerEnum(CONDITIONID_FEET)
  1158. registerEnum(CONDITIONID_RING)
  1159. registerEnum(CONDITIONID_AMMO)
  1160.  
  1161. registerEnum(CONDITION_PARAM_OWNER)
  1162. registerEnum(CONDITION_PARAM_TICKS)
  1163. registerEnum(CONDITION_PARAM_HEALTHGAIN)
  1164. registerEnum(CONDITION_PARAM_HEALTHTICKS)
  1165. registerEnum(CONDITION_PARAM_MANAGAIN)
  1166. registerEnum(CONDITION_PARAM_MANATICKS)
  1167. registerEnum(CONDITION_PARAM_DELAYED)
  1168. registerEnum(CONDITION_PARAM_SPEED)
  1169. registerEnum(CONDITION_PARAM_LIGHT_LEVEL)
  1170. registerEnum(CONDITION_PARAM_LIGHT_COLOR)
  1171. registerEnum(CONDITION_PARAM_SOULGAIN)
  1172. registerEnum(CONDITION_PARAM_SOULTICKS)
  1173. registerEnum(CONDITION_PARAM_MINVALUE)
  1174. registerEnum(CONDITION_PARAM_MAXVALUE)
  1175. registerEnum(CONDITION_PARAM_STARTVALUE)
  1176. registerEnum(CONDITION_PARAM_TICKINTERVAL)
  1177. registerEnum(CONDITION_PARAM_FORCEUPDATE)
  1178. registerEnum(CONDITION_PARAM_SKILL_MELEE)
  1179. registerEnum(CONDITION_PARAM_SKILL_FIST)
  1180. registerEnum(CONDITION_PARAM_SKILL_CLUB)
  1181. registerEnum(CONDITION_PARAM_SKILL_SWORD)
  1182. registerEnum(CONDITION_PARAM_SKILL_AXE)
  1183. registerEnum(CONDITION_PARAM_SKILL_DISTANCE)
  1184. registerEnum(CONDITION_PARAM_SKILL_SHIELD)
  1185. registerEnum(CONDITION_PARAM_SKILL_FISHING)
  1186. registerEnum(CONDITION_PARAM_STAT_MAXHITPOINTS)
  1187. registerEnum(CONDITION_PARAM_STAT_MAXMANAPOINTS)
  1188. registerEnum(CONDITION_PARAM_STAT_MAGICPOINTS)
  1189. registerEnum(CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT)
  1190. registerEnum(CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT)
  1191. registerEnum(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT)
  1192. registerEnum(CONDITION_PARAM_PERIODICDAMAGE)
  1193. registerEnum(CONDITION_PARAM_SKILL_MELEEPERCENT)
  1194. registerEnum(CONDITION_PARAM_SKILL_FISTPERCENT)
  1195. registerEnum(CONDITION_PARAM_SKILL_CLUBPERCENT)
  1196. registerEnum(CONDITION_PARAM_SKILL_SWORDPERCENT)
  1197. registerEnum(CONDITION_PARAM_SKILL_AXEPERCENT)
  1198. registerEnum(CONDITION_PARAM_SKILL_DISTANCEPERCENT)
  1199. registerEnum(CONDITION_PARAM_SKILL_SHIELDPERCENT)
  1200. registerEnum(CONDITION_PARAM_SKILL_FISHINGPERCENT)
  1201. registerEnum(CONDITION_PARAM_BUFF_SPELL)
  1202. registerEnum(CONDITION_PARAM_SUBID)
  1203. registerEnum(CONDITION_PARAM_FIELD)
  1204.  
  1205. registerEnum(CONST_ME_NONE)
  1206. registerEnum(CONST_ME_DRAWBLOOD)
  1207. registerEnum(CONST_ME_LOSEENERGY)
  1208. registerEnum(CONST_ME_POFF)
  1209. registerEnum(CONST_ME_BLOCKHIT)
  1210. registerEnum(CONST_ME_EXPLOSIONAREA)
  1211. registerEnum(CONST_ME_EXPLOSIONHIT)
  1212. registerEnum(CONST_ME_FIREAREA)
  1213. registerEnum(CONST_ME_YELLOW_RINGS)
  1214. registerEnum(CONST_ME_GREEN_RINGS)
  1215. registerEnum(CONST_ME_HITAREA)
  1216. registerEnum(CONST_ME_TELEPORT)
  1217. registerEnum(CONST_ME_ENERGYHIT)
  1218. registerEnum(CONST_ME_MAGIC_BLUE)
  1219. registerEnum(CONST_ME_MAGIC_RED)
  1220. registerEnum(CONST_ME_MAGIC_GREEN)
  1221. registerEnum(CONST_ME_HITBYFIRE)
  1222. registerEnum(CONST_ME_HITBYPOISON)
  1223. registerEnum(CONST_ME_MORTAREA)
  1224. registerEnum(CONST_ME_SOUND_GREEN)
  1225. registerEnum(CONST_ME_SOUND_RED)
  1226. registerEnum(CONST_ME_POISONAREA)
  1227. registerEnum(CONST_ME_SOUND_YELLOW)
  1228. registerEnum(CONST_ME_SOUND_PURPLE)
  1229. registerEnum(CONST_ME_SOUND_BLUE)
  1230. registerEnum(CONST_ME_SOUND_WHITE)
  1231. registerEnum(CONST_ME_BUBBLES)
  1232. registerEnum(CONST_ME_CRAPS)
  1233. registerEnum(CONST_ME_GIFT_WRAPS)
  1234. registerEnum(CONST_ME_FIREWORK_YELLOW)
  1235. registerEnum(CONST_ME_FIREWORK_RED)
  1236. registerEnum(CONST_ME_FIREWORK_BLUE)
  1237. registerEnum(CONST_ME_STUN)
  1238. registerEnum(CONST_ME_SLEEP)
  1239. registerEnum(CONST_ME_WATERCREATURE)
  1240. registerEnum(CONST_ME_GROUNDSHAKER)
  1241. registerEnum(CONST_ME_HEARTS)
  1242. registerEnum(CONST_ME_FIREATTACK)
  1243. registerEnum(CONST_ME_ENERGYAREA)
  1244. registerEnum(CONST_ME_SMALLCLOUDS)
  1245. registerEnum(CONST_ME_HOLYDAMAGE)
  1246. registerEnum(CONST_ME_BIGCLOUDS)
  1247. registerEnum(CONST_ME_ICEAREA)
  1248. registerEnum(CONST_ME_ICETORNADO)
  1249. registerEnum(CONST_ME_ICEATTACK)
  1250. registerEnum(CONST_ME_STONES)
  1251. registerEnum(CONST_ME_SMALLPLANTS)
  1252. registerEnum(CONST_ME_CARNIPHILA)
  1253. registerEnum(CONST_ME_PURPLEENERGY)
  1254. registerEnum(CONST_ME_YELLOWENERGY)
  1255. registerEnum(CONST_ME_HOLYAREA)
  1256. registerEnum(CONST_ME_BIGPLANTS)
  1257. registerEnum(CONST_ME_CAKE)
  1258. registerEnum(CONST_ME_GIANTICE)
  1259. registerEnum(CONST_ME_WATERSPLASH)
  1260. registerEnum(CONST_ME_PLANTATTACK)
  1261. registerEnum(CONST_ME_TUTORIALARROW)
  1262. registerEnum(CONST_ME_TUTORIALSQUARE)
  1263. registerEnum(CONST_ME_MIRRORHORIZONTAL)
  1264. registerEnum(CONST_ME_MIRRORVERTICAL)
  1265. registerEnum(CONST_ME_SKULLHORIZONTAL)
  1266. registerEnum(CONST_ME_SKULLVERTICAL)
  1267. registerEnum(CONST_ME_ASSASSIN)
  1268. registerEnum(CONST_ME_STEPSHORIZONTAL)
  1269. registerEnum(CONST_ME_BLOODYSTEPS)
  1270. registerEnum(CONST_ME_STEPSVERTICAL)
  1271. registerEnum(CONST_ME_YALAHARIGHOST)
  1272. registerEnum(CONST_ME_BATS)
  1273. registerEnum(CONST_ME_SMOKE)
  1274. registerEnum(CONST_ME_INSECTS)
  1275. registerEnum(CONST_ME_DRAGONHEAD)
  1276. registerEnum(CONST_ME_ORCSHAMAN)
  1277. registerEnum(CONST_ME_ORCSHAMAN_FIRE)
  1278. registerEnum(CONST_ME_THUNDER)
  1279. registerEnum(CONST_ME_FERUMBRAS)
  1280. registerEnum(CONST_ME_CONFETTI_HORIZONTAL)
  1281. registerEnum(CONST_ME_CONFETTI_VERTICAL)
  1282. registerEnum(CONST_ME_BLACKSMOKE)
  1283. registerEnum(CONST_ME_REDSMOKE)
  1284. registerEnum(CONST_ME_YELLOWSMOKE)
  1285. registerEnum(CONST_ME_GREENSMOKE)
  1286. registerEnum(CONST_ME_PURPLESMOKE)
  1287.  
  1288. registerEnum(CONST_ANI_NONE)
  1289. registerEnum(CONST_ANI_SPEAR)
  1290. registerEnum(CONST_ANI_BOLT)
  1291. registerEnum(CONST_ANI_ARROW)
  1292. registerEnum(CONST_ANI_FIRE)
  1293. registerEnum(CONST_ANI_ENERGY)
  1294. registerEnum(CONST_ANI_POISONARROW)
  1295. registerEnum(CONST_ANI_BURSTARROW)
  1296. registerEnum(CONST_ANI_THROWINGSTAR)
  1297. registerEnum(CONST_ANI_THROWINGKNIFE)
  1298. registerEnum(CONST_ANI_SMALLSTONE)
  1299. registerEnum(CONST_ANI_DEATH)
  1300. registerEnum(CONST_ANI_LARGEROCK)
  1301. registerEnum(CONST_ANI_SNOWBALL)
  1302. registerEnum(CONST_ANI_POWERBOLT)
  1303. registerEnum(CONST_ANI_POISON)
  1304. registerEnum(CONST_ANI_INFERNALBOLT)
  1305. registerEnum(CONST_ANI_HUNTINGSPEAR)
  1306. registerEnum(CONST_ANI_ENCHANTEDSPEAR)
  1307. registerEnum(CONST_ANI_REDSTAR)
  1308. registerEnum(CONST_ANI_GREENSTAR)
  1309. registerEnum(CONST_ANI_ROYALSPEAR)
  1310. registerEnum(CONST_ANI_SNIPERARROW)
  1311. registerEnum(CONST_ANI_ONYXARROW)
  1312. registerEnum(CONST_ANI_PIERCINGBOLT)
  1313. registerEnum(CONST_ANI_WHIRLWINDSWORD)
  1314. registerEnum(CONST_ANI_WHIRLWINDAXE)
  1315. registerEnum(CONST_ANI_WHIRLWINDCLUB)
  1316. registerEnum(CONST_ANI_ETHEREALSPEAR)
  1317. registerEnum(CONST_ANI_ICE)
  1318. registerEnum(CONST_ANI_EARTH)
  1319. registerEnum(CONST_ANI_HOLY)
  1320. registerEnum(CONST_ANI_SUDDENDEATH)
  1321. registerEnum(CONST_ANI_FLASHARROW)
  1322. registerEnum(CONST_ANI_FLAMMINGARROW)
  1323. registerEnum(CONST_ANI_SHIVERARROW)
  1324. registerEnum(CONST_ANI_ENERGYBALL)
  1325. registerEnum(CONST_ANI_SMALLICE)
  1326. registerEnum(CONST_ANI_SMALLHOLY)
  1327. registerEnum(CONST_ANI_SMALLEARTH)
  1328. registerEnum(CONST_ANI_EARTHARROW)
  1329. registerEnum(CONST_ANI_EXPLOSION)
  1330. registerEnum(CONST_ANI_CAKE)
  1331. registerEnum(CONST_ANI_TARSALARROW)
  1332. registerEnum(CONST_ANI_VORTEXBOLT)
  1333. registerEnum(CONST_ANI_PRISMATICBOLT)
  1334. registerEnum(CONST_ANI_CRYSTALLINEARROW)
  1335. registerEnum(CONST_ANI_DRILLBOLT)
  1336. registerEnum(CONST_ANI_ENVENOMEDARROW)
  1337. registerEnum(CONST_ANI_GLOOTHSPEAR)
  1338. registerEnum(CONST_ANI_SIMPLEARROW)
  1339. registerEnum(CONST_ANI_WEAPONTYPE)
  1340.  
  1341. registerEnum(CONST_PROP_BLOCKSOLID)
  1342. registerEnum(CONST_PROP_HASHEIGHT)
  1343. registerEnum(CONST_PROP_BLOCKPROJECTILE)
  1344. registerEnum(CONST_PROP_BLOCKPATH)
  1345. registerEnum(CONST_PROP_ISVERTICAL)
  1346. registerEnum(CONST_PROP_ISHORIZONTAL)
  1347. registerEnum(CONST_PROP_MOVEABLE)
  1348. registerEnum(CONST_PROP_IMMOVABLEBLOCKSOLID)
  1349. registerEnum(CONST_PROP_IMMOVABLEBLOCKPATH)
  1350. registerEnum(CONST_PROP_IMMOVABLENOFIELDBLOCKPATH)
  1351. registerEnum(CONST_PROP_NOFIELDBLOCKPATH)
  1352. registerEnum(CONST_PROP_SUPPORTHANGABLE)
  1353.  
  1354. registerEnum(CONST_SLOT_HEAD)
  1355. registerEnum(CONST_SLOT_NECKLACE)
  1356. registerEnum(CONST_SLOT_BACKPACK)
  1357. registerEnum(CONST_SLOT_ARMOR)
  1358. registerEnum(CONST_SLOT_RIGHT)
  1359. registerEnum(CONST_SLOT_LEFT)
  1360. registerEnum(CONST_SLOT_LEGS)
  1361. registerEnum(CONST_SLOT_FEET)
  1362. registerEnum(CONST_SLOT_RING)
  1363. registerEnum(CONST_SLOT_AMMO)
  1364.  
  1365. registerEnum(GAME_STATE_STARTUP)
  1366. registerEnum(GAME_STATE_INIT)
  1367. registerEnum(GAME_STATE_NORMAL)
  1368. registerEnum(GAME_STATE_CLOSED)
  1369. registerEnum(GAME_STATE_SHUTDOWN)
  1370. registerEnum(GAME_STATE_CLOSING)
  1371. registerEnum(GAME_STATE_MAINTAIN)
  1372.  
  1373. registerEnum(MESSAGE_STATUS_CONSOLE_BLUE)
  1374. registerEnum(MESSAGE_STATUS_CONSOLE_RED)
  1375. registerEnum(MESSAGE_STATUS_DEFAULT)
  1376. registerEnum(MESSAGE_STATUS_WARNING)
  1377. registerEnum(MESSAGE_EVENT_ADVANCE)
  1378. registerEnum(MESSAGE_STATUS_SMALL)
  1379. registerEnum(MESSAGE_INFO_DESCR)
  1380. registerEnum(MESSAGE_DAMAGE_DEALT)
  1381. registerEnum(MESSAGE_DAMAGE_RECEIVED)
  1382. registerEnum(MESSAGE_HEALED)
  1383. registerEnum(MESSAGE_EXPERIENCE)
  1384. registerEnum(MESSAGE_DAMAGE_OTHERS)
  1385. registerEnum(MESSAGE_HEALED_OTHERS)
  1386. registerEnum(MESSAGE_EXPERIENCE_OTHERS)
  1387. registerEnum(MESSAGE_EVENT_DEFAULT)
  1388. registerEnum(MESSAGE_EVENT_ORANGE)
  1389. registerEnum(MESSAGE_STATUS_CONSOLE_ORANGE)
  1390.  
  1391. registerEnum(CREATURETYPE_PLAYER)
  1392. registerEnum(CREATURETYPE_MONSTER)
  1393. registerEnum(CREATURETYPE_NPC)
  1394. registerEnum(CREATURETYPE_SUMMON_OWN)
  1395. registerEnum(CREATURETYPE_SUMMON_OTHERS)
  1396.  
  1397. registerEnum(CLIENTOS_LINUX)
  1398. registerEnum(CLIENTOS_WINDOWS)
  1399. registerEnum(CLIENTOS_FLASH)
  1400. registerEnum(CLIENTOS_OTCLIENT_LINUX)
  1401. registerEnum(CLIENTOS_OTCLIENT_WINDOWS)
  1402. registerEnum(CLIENTOS_OTCLIENT_MAC)
  1403.  
  1404. registerEnum(ITEM_ATTRIBUTE_NONE)
  1405. registerEnum(ITEM_ATTRIBUTE_ACTIONID)
  1406. registerEnum(ITEM_ATTRIBUTE_UNIQUEID)
  1407. registerEnum(ITEM_ATTRIBUTE_DESCRIPTION)
  1408. registerEnum(ITEM_ATTRIBUTE_TEXT)
  1409. registerEnum(ITEM_ATTRIBUTE_DATE)
  1410. registerEnum(ITEM_ATTRIBUTE_WRITER)
  1411. registerEnum(ITEM_ATTRIBUTE_NAME)
  1412. registerEnum(ITEM_ATTRIBUTE_ARTICLE)
  1413. registerEnum(ITEM_ATTRIBUTE_PLURALNAME)
  1414. registerEnum(ITEM_ATTRIBUTE_WEIGHT)
  1415. registerEnum(ITEM_ATTRIBUTE_ATTACK)
  1416. registerEnum(ITEM_ATTRIBUTE_DEFENSE)
  1417. registerEnum(ITEM_ATTRIBUTE_EXTRADEFENSE)
  1418. registerEnum(ITEM_ATTRIBUTE_ARMOR)
  1419. registerEnum(ITEM_ATTRIBUTE_HITCHANCE)
  1420. registerEnum(ITEM_ATTRIBUTE_SHOOTRANGE)
  1421. registerEnum(ITEM_ATTRIBUTE_OWNER)
  1422. registerEnum(ITEM_ATTRIBUTE_DURATION)
  1423. registerEnum(ITEM_ATTRIBUTE_DECAYSTATE)
  1424. registerEnum(ITEM_ATTRIBUTE_CORPSEOWNER)
  1425. registerEnum(ITEM_ATTRIBUTE_CHARGES)
  1426. registerEnum(ITEM_ATTRIBUTE_FLUIDTYPE)
  1427. registerEnum(ITEM_ATTRIBUTE_DOORID)
  1428.  
  1429. registerEnum(ITEM_TYPE_DEPOT)
  1430. registerEnum(ITEM_TYPE_REWARDCHEST)
  1431. registerEnum(ITEM_TYPE_MAILBOX)
  1432. registerEnum(ITEM_TYPE_TRASHHOLDER)
  1433. registerEnum(ITEM_TYPE_CONTAINER)
  1434. registerEnum(ITEM_TYPE_DOOR)
  1435. registerEnum(ITEM_TYPE_MAGICFIELD)
  1436. registerEnum(ITEM_TYPE_TELEPORT)
  1437. registerEnum(ITEM_TYPE_BED)
  1438. registerEnum(ITEM_TYPE_KEY)
  1439. registerEnum(ITEM_TYPE_RUNE)
  1440.  
  1441. registerEnum(ITEM_BAG)
  1442. registerEnum(ITEM_GOLD_COIN)
  1443. registerEnum(ITEM_REWARD_CHEST)
  1444. registerEnum(ITEM_REWARD_CONTAINER)
  1445. registerEnum(ITEM_PLATINUM_COIN)
  1446. registerEnum(ITEM_CRYSTAL_COIN)
  1447. registerEnum(ITEM_AMULETOFLOSS)
  1448. registerEnum(ITEM_PARCEL)
  1449. registerEnum(ITEM_LABEL)
  1450. registerEnum(ITEM_FIREFIELD_PVP_FULL)
  1451. registerEnum(ITEM_FIREFIELD_PVP_MEDIUM)
  1452. registerEnum(ITEM_FIREFIELD_PVP_SMALL)
  1453. registerEnum(ITEM_FIREFIELD_PERSISTENT_FULL)
  1454. registerEnum(ITEM_FIREFIELD_PERSISTENT_MEDIUM)
  1455. registerEnum(ITEM_FIREFIELD_PERSISTENT_SMALL)
  1456. registerEnum(ITEM_FIREFIELD_NOPVP)
  1457. registerEnum(ITEM_POISONFIELD_PVP)
  1458. registerEnum(ITEM_POISONFIELD_PERSISTENT)
  1459. registerEnum(ITEM_POISONFIELD_NOPVP)
  1460. registerEnum(ITEM_ENERGYFIELD_PVP)
  1461. registerEnum(ITEM_ENERGYFIELD_PERSISTENT)
  1462. registerEnum(ITEM_ENERGYFIELD_NOPVP)
  1463. registerEnum(ITEM_MAGICWALL)
  1464. registerEnum(ITEM_MAGICWALL_PERSISTENT)
  1465. registerEnum(ITEM_MAGICWALL_SAFE)
  1466. registerEnum(ITEM_WILDGROWTH)
  1467. registerEnum(ITEM_WILDGROWTH_PERSISTENT)
  1468. registerEnum(ITEM_WILDGROWTH_SAFE)
  1469.  
  1470. registerEnum(PlayerFlag_CannotUseCombat)
  1471. registerEnum(PlayerFlag_CannotAttackPlayer)
  1472. registerEnum(PlayerFlag_CannotAttackMonster)
  1473. registerEnum(PlayerFlag_CannotBeAttacked)
  1474. registerEnum(PlayerFlag_CanConvinceAll)
  1475. registerEnum(PlayerFlag_CanSummonAll)
  1476. registerEnum(PlayerFlag_CanIllusionAll)
  1477. registerEnum(PlayerFlag_CanSenseInvisibility)
  1478. registerEnum(PlayerFlag_IgnoredByMonsters)
  1479. registerEnum(PlayerFlag_NotGainInFight)
  1480. registerEnum(PlayerFlag_HasInfiniteMana)
  1481. registerEnum(PlayerFlag_HasInfiniteSoul)
  1482. registerEnum(PlayerFlag_HasNoExhaustion)
  1483. registerEnum(PlayerFlag_CannotUseSpells)
  1484. registerEnum(PlayerFlag_CannotPickupItem)
  1485. registerEnum(PlayerFlag_CanAlwaysLogin)
  1486. registerEnum(PlayerFlag_CanBroadcast)
  1487. registerEnum(PlayerFlag_CanEditHouses)
  1488. registerEnum(PlayerFlag_CannotBeBanned)
  1489. registerEnum(PlayerFlag_CannotBePushed)
  1490. registerEnum(PlayerFlag_HasInfiniteCapacity)
  1491. registerEnum(PlayerFlag_CanPushAllCreatures)
  1492. registerEnum(PlayerFlag_CanTalkRedPrivate)
  1493. registerEnum(PlayerFlag_CanTalkRedChannel)
  1494. registerEnum(PlayerFlag_TalkOrangeHelpChannel)
  1495. registerEnum(PlayerFlag_NotGainExperience)
  1496. registerEnum(PlayerFlag_NotGainMana)
  1497. registerEnum(PlayerFlag_NotGainHealth)
  1498. registerEnum(PlayerFlag_NotGainSkill)
  1499. registerEnum(PlayerFlag_SetMaxSpeed)
  1500. registerEnum(PlayerFlag_SpecialVIP)
  1501. registerEnum(PlayerFlag_NotGenerateLoot)
  1502. registerEnum(PlayerFlag_CanTalkRedChannelAnonymous)
  1503. registerEnum(PlayerFlag_IgnoreProtectionZone)
  1504. registerEnum(PlayerFlag_IgnoreSpellCheck)
  1505. registerEnum(PlayerFlag_IgnoreWeaponCheck)
  1506. registerEnum(PlayerFlag_CannotBeMuted)
  1507. registerEnum(PlayerFlag_IsAlwaysPremium)
  1508.  
  1509. registerEnum(PLAYERSEX_FEMALE)
  1510. registerEnum(PLAYERSEX_MALE)
  1511.  
  1512. registerEnum(VOCATION_NONE)
  1513.  
  1514. registerEnum(SKILL_FIST)
  1515. registerEnum(SKILL_CLUB)
  1516. registerEnum(SKILL_SWORD)
  1517. registerEnum(SKILL_AXE)
  1518. registerEnum(SKILL_DISTANCE)
  1519. registerEnum(SKILL_SHIELD)
  1520. registerEnum(SKILL_FISHING)
  1521. registerEnum(SKILL_MAGLEVEL)
  1522. registerEnum(SKILL_LEVEL)
  1523.  
  1524. registerEnum(SKULL_NONE)
  1525. registerEnum(SKULL_YELLOW)
  1526. registerEnum(SKULL_GREEN)
  1527. registerEnum(SKULL_WHITE)
  1528. registerEnum(SKULL_RED)
  1529. registerEnum(SKULL_BLACK)
  1530. registerEnum(SKULL_ORANGE)
  1531.  
  1532. registerEnum(TALKTYPE_SAY)
  1533. registerEnum(TALKTYPE_WHISPER)
  1534. registerEnum(TALKTYPE_YELL)
  1535. registerEnum(TALKTYPE_PRIVATE_FROM)
  1536. registerEnum(TALKTYPE_PRIVATE_TO)
  1537. registerEnum(TALKTYPE_CHANNEL_Y)
  1538. registerEnum(TALKTYPE_CHANNEL_O)
  1539. registerEnum(TALKTYPE_PRIVATE_NP)
  1540. registerEnum(TALKTYPE_PRIVATE_PN)
  1541. registerEnum(TALKTYPE_BROADCAST)
  1542. registerEnum(TALKTYPE_CHANNEL_R1)
  1543. registerEnum(TALKTYPE_PRIVATE_RED_FROM)
  1544. registerEnum(TALKTYPE_PRIVATE_RED_TO)
  1545. registerEnum(TALKTYPE_MONSTER_SAY)
  1546. registerEnum(TALKTYPE_MONSTER_YELL)
  1547. registerEnum(TALKTYPE_CHANNEL_R2)
  1548.  
  1549. registerEnum(TEXTCOLOR_BLUE)
  1550. registerEnum(TEXTCOLOR_LIGHTGREEN)
  1551. registerEnum(TEXTCOLOR_LIGHTBLUE)
  1552. registerEnum(TEXTCOLOR_MAYABLUE)
  1553. registerEnum(TEXTCOLOR_DARKRED)
  1554. registerEnum(TEXTCOLOR_LIGHTGREY)
  1555. registerEnum(TEXTCOLOR_SKYBLUE)
  1556. registerEnum(TEXTCOLOR_PURPLE)
  1557. registerEnum(TEXTCOLOR_RED)
  1558. registerEnum(TEXTCOLOR_ORANGE)
  1559. registerEnum(TEXTCOLOR_YELLOW)
  1560. registerEnum(TEXTCOLOR_WHITE_EXP)
  1561. registerEnum(TEXTCOLOR_NONE)
  1562.  
  1563. registerEnum(TILESTATE_NONE)
  1564. registerEnum(TILESTATE_PROTECTIONZONE)
  1565. registerEnum(TILESTATE_NOPVPZONE)
  1566. registerEnum(TILESTATE_NOLOGOUT)
  1567. registerEnum(TILESTATE_PVPZONE)
  1568. registerEnum(TILESTATE_FLOORCHANGE)
  1569. registerEnum(TILESTATE_FLOORCHANGE_DOWN)
  1570. registerEnum(TILESTATE_FLOORCHANGE_NORTH)
  1571. registerEnum(TILESTATE_FLOORCHANGE_SOUTH)
  1572. registerEnum(TILESTATE_FLOORCHANGE_EAST)
  1573. registerEnum(TILESTATE_FLOORCHANGE_WEST)
  1574. registerEnum(TILESTATE_TELEPORT)
  1575. registerEnum(TILESTATE_MAGICFIELD)
  1576. registerEnum(TILESTATE_MAILBOX)
  1577. registerEnum(TILESTATE_TRASHHOLDER)
  1578. registerEnum(TILESTATE_BED)
  1579. registerEnum(TILESTATE_DEPOT)
  1580. registerEnum(TILESTATE_BLOCKSOLID)
  1581. registerEnum(TILESTATE_BLOCKPATH)
  1582. registerEnum(TILESTATE_IMMOVABLEBLOCKSOLID)
  1583. registerEnum(TILESTATE_IMMOVABLEBLOCKPATH)
  1584. registerEnum(TILESTATE_IMMOVABLENOFIELDBLOCKPATH)
  1585. registerEnum(TILESTATE_NOFIELDBLOCKPATH)
  1586. registerEnum(TILESTATE_FLOORCHANGE_SOUTH_ALT)
  1587. registerEnum(TILESTATE_FLOORCHANGE_EAST_ALT)
  1588. registerEnum(TILESTATE_SUPPORTS_HANGABLE)
  1589.  
  1590. registerEnum(WEAPON_NONE)
  1591. registerEnum(WEAPON_SWORD)
  1592. registerEnum(WEAPON_CLUB)
  1593. registerEnum(WEAPON_AXE)
  1594. registerEnum(WEAPON_SHIELD)
  1595. registerEnum(WEAPON_DISTANCE)
  1596. registerEnum(WEAPON_WAND)
  1597. registerEnum(WEAPON_AMMO)
  1598.  
  1599. registerEnum(WORLD_TYPE_NO_PVP)
  1600. registerEnum(WORLD_TYPE_PVP)
  1601. registerEnum(WORLD_TYPE_PVP_ENFORCED)
  1602.  
  1603. // Use with container:addItem, container:addItemEx and possibly other functions.
  1604. registerEnum(FLAG_NOLIMIT)
  1605. registerEnum(FLAG_IGNOREBLOCKITEM)
  1606. registerEnum(FLAG_IGNOREBLOCKCREATURE)
  1607. registerEnum(FLAG_CHILDISOWNER)
  1608. registerEnum(FLAG_PATHFINDING)
  1609. registerEnum(FLAG_IGNOREFIELDDAMAGE)
  1610. registerEnum(FLAG_IGNORENOTMOVEABLE)
  1611. registerEnum(FLAG_IGNOREAUTOSTACK)
  1612.  
  1613. // Use with itemType:getSlotPosition
  1614. registerEnum(SLOTP_WHEREEVER)
  1615. registerEnum(SLOTP_HEAD)
  1616. registerEnum(SLOTP_NECKLACE)
  1617. registerEnum(SLOTP_BACKPACK)
  1618. registerEnum(SLOTP_ARMOR)
  1619. registerEnum(SLOTP_RIGHT)
  1620. registerEnum(SLOTP_LEFT)
  1621. registerEnum(SLOTP_LEGS)
  1622. registerEnum(SLOTP_FEET)
  1623. registerEnum(SLOTP_RING)
  1624. registerEnum(SLOTP_AMMO)
  1625. registerEnum(SLOTP_DEPOT)
  1626. registerEnum(SLOTP_TWO_HAND)
  1627.  
  1628. // Use with combat functions
  1629. registerEnum(ORIGIN_NONE)
  1630. registerEnum(ORIGIN_CONDITION)
  1631. registerEnum(ORIGIN_SPELL)
  1632. registerEnum(ORIGIN_MELEE)
  1633. registerEnum(ORIGIN_RANGED)
  1634.  
  1635. // Use with house:getAccessList, house:setAccessList
  1636. registerEnum(GUEST_LIST)
  1637. registerEnum(SUBOWNER_LIST)
  1638.  
  1639. // Use with npc:setSpeechBubble
  1640. registerEnum(SPEECHBUBBLE_NONE)
  1641. registerEnum(SPEECHBUBBLE_NORMAL)
  1642. registerEnum(SPEECHBUBBLE_TRADE)
  1643. registerEnum(SPEECHBUBBLE_QUEST)
  1644. registerEnum(SPEECHBUBBLE_QUESTTRADER)
  1645.  
  1646. // Use with player:addMapMark
  1647. registerEnum(MAPMARK_TICK)
  1648. registerEnum(MAPMARK_QUESTION)
  1649. registerEnum(MAPMARK_EXCLAMATION)
  1650. registerEnum(MAPMARK_STAR)
  1651. registerEnum(MAPMARK_CROSS)
  1652. registerEnum(MAPMARK_TEMPLE)
  1653. registerEnum(MAPMARK_KISS)
  1654. registerEnum(MAPMARK_SHOVEL)
  1655. registerEnum(MAPMARK_SWORD)
  1656. registerEnum(MAPMARK_FLAG)
  1657. registerEnum(MAPMARK_LOCK)
  1658. registerEnum(MAPMARK_BAG)
  1659. registerEnum(MAPMARK_SKULL)
  1660. registerEnum(MAPMARK_DOLLAR)
  1661. registerEnum(MAPMARK_REDNORTH)
  1662. registerEnum(MAPMARK_REDSOUTH)
  1663. registerEnum(MAPMARK_REDEAST)
  1664. registerEnum(MAPMARK_REDWEST)
  1665. registerEnum(MAPMARK_GREENNORTH)
  1666. registerEnum(MAPMARK_GREENSOUTH)
  1667.  
  1668. // Use with Game.getReturnMessage
  1669. registerEnum(RETURNVALUE_NOERROR)
  1670. registerEnum(RETURNVALUE_NOTPOSSIBLE)
  1671. registerEnum(RETURNVALUE_NOTENOUGHROOM)
  1672. registerEnum(RETURNVALUE_PLAYERISPZLOCKED)
  1673. registerEnum(RETURNVALUE_PLAYERISNOTINVITED)
  1674. registerEnum(RETURNVALUE_CANNOTTHROW)
  1675. registerEnum(RETURNVALUE_THEREISNOWAY)
  1676. registerEnum(RETURNVALUE_DESTINATIONOUTOFREACH)
  1677. registerEnum(RETURNVALUE_CREATUREBLOCK)
  1678. registerEnum(RETURNVALUE_NOTMOVEABLE)
  1679. registerEnum(RETURNVALUE_DROPTWOHANDEDITEM)
  1680. registerEnum(RETURNVALUE_BOTHHANDSNEEDTOBEFREE)
  1681. registerEnum(RETURNVALUE_CANONLYUSEONEWEAPON)
  1682. registerEnum(RETURNVALUE_NEEDEXCHANGE)
  1683. registerEnum(RETURNVALUE_CANNOTBEDRESSED)
  1684. registerEnum(RETURNVALUE_PUTTHISOBJECTINYOURHAND)
  1685. registerEnum(RETURNVALUE_PUTTHISOBJECTINBOTHHANDS)
  1686. registerEnum(RETURNVALUE_TOOFARAWAY)
  1687. registerEnum(RETURNVALUE_FIRSTGODOWNSTAIRS)
  1688. registerEnum(RETURNVALUE_FIRSTGOUPSTAIRS)
  1689. registerEnum(RETURNVALUE_CONTAINERNOTENOUGHROOM)
  1690. registerEnum(RETURNVALUE_NOTENOUGHCAPACITY)
  1691. registerEnum(RETURNVALUE_CANNOTPICKUP)
  1692. registerEnum(RETURNVALUE_THISISIMPOSSIBLE)
  1693. registerEnum(RETURNVALUE_DEPOTISFULL)
  1694. registerEnum(RETURNVALUE_CREATUREDOESNOTEXIST)
  1695. registerEnum(RETURNVALUE_CANNOTUSETHISOBJECT)
  1696. registerEnum(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
  1697. registerEnum(RETURNVALUE_NOTREQUIREDLEVELTOUSERUNE)
  1698. registerEnum(RETURNVALUE_YOUAREALREADYTRADING)
  1699. registerEnum(RETURNVALUE_THISPLAYERISALREADYTRADING)
  1700. registerEnum(RETURNVALUE_YOUMAYNOTLOGOUTDURINGAFIGHT)
  1701. registerEnum(RETURNVALUE_DIRECTPLAYERSHOOT)
  1702. registerEnum(RETURNVALUE_NOTENOUGHLEVEL)
  1703. registerEnum(RETURNVALUE_NOTENOUGHMAGICLEVEL)
  1704. registerEnum(RETURNVALUE_NOTENOUGHMANA)
  1705. registerEnum(RETURNVALUE_NOTENOUGHSOUL)
  1706. registerEnum(RETURNVALUE_YOUAREEXHAUSTED)
  1707. registerEnum(RETURNVALUE_PLAYERISNOTREACHABLE)
  1708. registerEnum(RETURNVALUE_CANONLYUSETHISRUNEONCREATURES)
  1709. registerEnum(RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE)
  1710. registerEnum(RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER)
  1711. registerEnum(RETURNVALUE_YOUMAYNOTATTACKAPERSONINPROTECTIONZONE)
  1712. registerEnum(RETURNVALUE_YOUMAYNOTATTACKAPERSONWHILEINPROTECTIONZONE)
  1713. registerEnum(RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE)
  1714. registerEnum(RETURNVALUE_YOUCANONLYUSEITONCREATURES)
  1715. registerEnum(RETURNVALUE_CREATUREISNOTREACHABLE)
  1716. registerEnum(RETURNVALUE_TURNSECUREMODETOATTACKUNMARKEDPLAYERS)
  1717. registerEnum(RETURNVALUE_YOUNEEDPREMIUMACCOUNT)
  1718. registerEnum(RETURNVALUE_YOUNEEDTOLEARNTHISSPELL)
  1719. registerEnum(RETURNVALUE_YOURVOCATIONCANNOTUSETHISSPELL)
  1720. registerEnum(RETURNVALUE_YOUNEEDAWEAPONTOUSETHISSPELL)
  1721. registerEnum(RETURNVALUE_PLAYERISPZLOCKEDLEAVEPVPZONE)
  1722. registerEnum(RETURNVALUE_PLAYERISPZLOCKEDENTERPVPZONE)
  1723. registerEnum(RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE)
  1724. registerEnum(RETURNVALUE_YOUCANNOTLOGOUTHERE)
  1725. registerEnum(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
  1726. registerEnum(RETURNVALUE_CANNOTCONJUREITEMHERE)
  1727. registerEnum(RETURNVALUE_YOUNEEDTOSPLITYOURSPEARS)
  1728. registerEnum(RETURNVALUE_NAMEISTOOAMBIGIOUS)
  1729. registerEnum(RETURNVALUE_CANONLYUSEONESHIELD)
  1730. registerEnum(RETURNVALUE_NOPARTYMEMBERSINRANGE)
  1731. registerEnum(RETURNVALUE_YOUARENOTTHEOWNER)
  1732.  
  1733. // _G
  1734. registerGlobalVariable("INDEX_WHEREEVER", INDEX_WHEREEVER);
  1735. registerGlobalBoolean("VIRTUAL_PARENT", true);
  1736.  
  1737. registerGlobalMethod("isType", LuaScriptInterface::luaIsType);
  1738. registerGlobalMethod("rawgetmetatable", LuaScriptInterface::luaRawGetMetatable);
  1739.  
  1740. // configKeys
  1741. registerTable("configKeys");
  1742.  
  1743. registerEnumIn("configKeys", ConfigManager::ALLOW_CHANGEOUTFIT)
  1744. registerEnumIn("configKeys", ConfigManager::ONE_PLAYER_ON_ACCOUNT)
  1745. registerEnumIn("configKeys", ConfigManager::AIMBOT_HOTKEY_ENABLED)
  1746. registerEnumIn("configKeys", ConfigManager::REMOVE_RUNE_CHARGES)
  1747. registerEnumIn("configKeys", ConfigManager::EXPERIENCE_FROM_PLAYERS)
  1748. registerEnumIn("configKeys", ConfigManager::FREE_PREMIUM)
  1749. registerEnumIn("configKeys", ConfigManager::REPLACE_KICK_ON_LOGIN)
  1750. registerEnumIn("configKeys", ConfigManager::ALLOW_CLONES)
  1751. registerEnumIn("configKeys", ConfigManager::BIND_ONLY_GLOBAL_ADDRESS)
  1752. registerEnumIn("configKeys", ConfigManager::OPTIMIZE_DATABASE)
  1753. registerEnumIn("configKeys", ConfigManager::MARKET_PREMIUM)
  1754. registerEnumIn("configKeys", ConfigManager::EMOTE_SPELLS)
  1755. registerEnumIn("configKeys", ConfigManager::STAMINA_SYSTEM)
  1756. registerEnumIn("configKeys", ConfigManager::WARN_UNSAFE_SCRIPTS)
  1757. registerEnumIn("configKeys", ConfigManager::CONVERT_UNSAFE_SCRIPTS)
  1758. registerEnumIn("configKeys", ConfigManager::CLASSIC_EQUIPMENT_SLOTS)
  1759.  
  1760. registerEnumIn("configKeys", ConfigManager::MAP_NAME)
  1761. registerEnumIn("configKeys", ConfigManager::HOUSE_RENT_PERIOD)
  1762. registerEnumIn("configKeys", ConfigManager::SERVER_NAME)
  1763. registerEnumIn("configKeys", ConfigManager::OWNER_NAME)
  1764. registerEnumIn("configKeys", ConfigManager::OWNER_EMAIL)
  1765. registerEnumIn("configKeys", ConfigManager::URL)
  1766. registerEnumIn("configKeys", ConfigManager::LOCATION)
  1767. registerEnumIn("configKeys", ConfigManager::IP)
  1768. registerEnumIn("configKeys", ConfigManager::MOTD)
  1769. registerEnumIn("configKeys", ConfigManager::WORLD_TYPE)
  1770. registerEnumIn("configKeys", ConfigManager::MYSQL_HOST)
  1771. registerEnumIn("configKeys", ConfigManager::MYSQL_USER)
  1772. registerEnumIn("configKeys", ConfigManager::MYSQL_PASS)
  1773. registerEnumIn("configKeys", ConfigManager::MYSQL_DB)
  1774. registerEnumIn("configKeys", ConfigManager::MYSQL_SOCK)
  1775. registerEnumIn("configKeys", ConfigManager::DEFAULT_PRIORITY)
  1776. registerEnumIn("configKeys", ConfigManager::MAP_AUTHOR)
  1777.  
  1778. registerEnumIn("configKeys", ConfigManager::SQL_PORT)
  1779. registerEnumIn("configKeys", ConfigManager::MAX_PLAYERS)
  1780. registerEnumIn("configKeys", ConfigManager::PZ_LOCKED)
  1781. registerEnumIn("configKeys", ConfigManager::DEFAULT_DESPAWNRANGE)
  1782. registerEnumIn("configKeys", ConfigManager::DEFAULT_DESPAWNRADIUS)
  1783. registerEnumIn("configKeys", ConfigManager::RATE_EXPERIENCE)
  1784. registerEnumIn("configKeys", ConfigManager::RATE_SKILL)
  1785. registerEnumIn("configKeys", ConfigManager::RATE_LOOT)
  1786. registerEnumIn("configKeys", ConfigManager::RATE_MAGIC)
  1787. registerEnumIn("configKeys", ConfigManager::RATE_SPAWN)
  1788. registerEnumIn("configKeys", ConfigManager::HOUSE_PRICE)
  1789. registerEnumIn("configKeys", ConfigManager::KILLS_TO_RED)
  1790. registerEnumIn("configKeys", ConfigManager::KILLS_TO_BLACK)
  1791. registerEnumIn("configKeys", ConfigManager::MAX_MESSAGEBUFFER)
  1792. registerEnumIn("configKeys", ConfigManager::ACTIONS_DELAY_INTERVAL)
  1793. registerEnumIn("configKeys", ConfigManager::EX_ACTIONS_DELAY_INTERVAL)
  1794. registerEnumIn("configKeys", ConfigManager::KICK_AFTER_MINUTES)
  1795. registerEnumIn("configKeys", ConfigManager::PROTECTION_LEVEL)
  1796. registerEnumIn("configKeys", ConfigManager::DEATH_LOSE_PERCENT)
  1797. registerEnumIn("configKeys", ConfigManager::STATUSQUERY_TIMEOUT)
  1798. registerEnumIn("configKeys", ConfigManager::FRAG_TIME)
  1799. registerEnumIn("configKeys", ConfigManager::WHITE_SKULL_TIME)
  1800. registerEnumIn("configKeys", ConfigManager::GAME_PORT)
  1801. registerEnumIn("configKeys", ConfigManager::LOGIN_PORT)
  1802. registerEnumIn("configKeys", ConfigManager::STATUS_PORT)
  1803. registerEnumIn("configKeys", ConfigManager::STAIRHOP_DELAY)
  1804. registerEnumIn("configKeys", ConfigManager::MARKET_OFFER_DURATION)
  1805. registerEnumIn("configKeys", ConfigManager::CHECK_EXPIRED_MARKET_OFFERS_EACH_MINUTES)
  1806. registerEnumIn("configKeys", ConfigManager::MAX_MARKET_OFFERS_AT_A_TIME_PER_PLAYER)
  1807. registerEnumIn("configKeys", ConfigManager::EXP_FROM_PLAYERS_LEVEL_RANGE)
  1808. registerEnumIn("configKeys", ConfigManager::MAX_PACKETS_PER_SECOND)
  1809.  
  1810. // os
  1811. registerMethod("os", "mtime", LuaScriptInterface::luaSystemTime);
  1812.  
  1813. // table
  1814. registerMethod("table", "create", LuaScriptInterface::luaTableCreate);
  1815.  
  1816. // Game
  1817. registerTable("Game");
  1818.  
  1819. registerMethod("Game", "getSpectators", LuaScriptInterface::luaGameGetSpectators);
  1820. registerMethod("Game", "getPlayers", LuaScriptInterface::luaGameGetPlayers);
  1821. registerMethod("Game", "loadMap", LuaScriptInterface::luaGameLoadMap);
  1822.  
  1823. registerMethod("Game", "getExperienceStage", LuaScriptInterface::luaGameGetExperienceStage);
  1824. registerMethod("Game", "getMonsterCount", LuaScriptInterface::luaGameGetMonsterCount);
  1825. registerMethod("Game", "getPlayerCount", LuaScriptInterface::luaGameGetPlayerCount);
  1826. registerMethod("Game", "getNpcCount", LuaScriptInterface::luaGameGetNpcCount);
  1827.  
  1828. registerMethod("Game", "getTowns", LuaScriptInterface::luaGameGetTowns);
  1829. registerMethod("Game", "getHouses", LuaScriptInterface::luaGameGetHouses);
  1830.  
  1831. registerMethod("Game", "getGameState", LuaScriptInterface::luaGameGetGameState);
  1832. registerMethod("Game", "setGameState", LuaScriptInterface::luaGameSetGameState);
  1833.  
  1834. registerMethod("Game", "getWorldType", LuaScriptInterface::luaGameGetWorldType);
  1835. registerMethod("Game", "setWorldType", LuaScriptInterface::luaGameSetWorldType);
  1836.  
  1837. registerMethod("Game", "getReturnMessage", LuaScriptInterface::luaGameGetReturnMessage);
  1838.  
  1839. registerMethod("Game", "createItem", LuaScriptInterface::luaGameCreateItem);
  1840. registerMethod("Game", "createContainer", LuaScriptInterface::luaGameCreateContainer);
  1841. registerMethod("Game", "createMonster", LuaScriptInterface::luaGameCreateMonster);
  1842. registerMethod("Game", "createNpc", LuaScriptInterface::luaGameCreateNpc);
  1843. registerMethod("Game", "createTile", LuaScriptInterface::luaGameCreateTile);
  1844.  
  1845. registerMethod("Game", "startRaid", LuaScriptInterface::luaGameStartRaid);
  1846.  
  1847. // Variant
  1848. registerClass("Variant", "", LuaScriptInterface::luaVariantCreate);
  1849.  
  1850. registerMethod("Variant", "getNumber", LuaScriptInterface::luaVariantGetNumber);
  1851. registerMethod("Variant", "getString", LuaScriptInterface::luaVariantGetString);
  1852. registerMethod("Variant", "getPosition", LuaScriptInterface::luaVariantGetPosition);
  1853.  
  1854. // Position
  1855. registerClass("Position", "", LuaScriptInterface::luaPositionCreate);
  1856. registerMetaMethod("Position", "__add", LuaScriptInterface::luaPositionAdd);
  1857. registerMetaMethod("Position", "__sub", LuaScriptInterface::luaPositionSub);
  1858. registerMetaMethod("Position", "__eq", LuaScriptInterface::luaPositionCompare);
  1859.  
  1860. registerMethod("Position", "getDistance", LuaScriptInterface::luaPositionGetDistance);
  1861. registerMethod("Position", "isSightClear", LuaScriptInterface::luaPositionIsSightClear);
  1862.  
  1863. registerMethod("Position", "sendMagicEffect", LuaScriptInterface::luaPositionSendMagicEffect);
  1864. registerMethod("Position", "sendDistanceEffect", LuaScriptInterface::luaPositionSendDistanceEffect);
  1865.  
  1866. // Tile
  1867. registerClass("Tile", "", LuaScriptInterface::luaTileCreate);
  1868. registerMetaMethod("Tile", "__eq", LuaScriptInterface::luaUserdataCompare);
  1869.  
  1870. registerMethod("Tile", "getPosition", LuaScriptInterface::luaTileGetPosition);
  1871. registerMethod("Tile", "getGround", LuaScriptInterface::luaTileGetGround);
  1872. registerMethod("Tile", "getThing", LuaScriptInterface::luaTileGetThing);
  1873. registerMethod("Tile", "getThingCount", LuaScriptInterface::luaTileGetThingCount);
  1874. registerMethod("Tile", "getTopVisibleThing", LuaScriptInterface::luaTileGetTopVisibleThing);
  1875.  
  1876. registerMethod("Tile", "getTopTopItem", LuaScriptInterface::luaTileGetTopTopItem);
  1877. registerMethod("Tile", "getTopDownItem", LuaScriptInterface::luaTileGetTopDownItem);
  1878. registerMethod("Tile", "getFieldItem", LuaScriptInterface::luaTileGetFieldItem);
  1879.  
  1880. registerMethod("Tile", "getItemById", LuaScriptInterface::luaTileGetItemById);
  1881. registerMethod("Tile", "getItemByType", LuaScriptInterface::luaTileGetItemByType);
  1882. registerMethod("Tile", "getItemByTopOrder", LuaScriptInterface::luaTileGetItemByTopOrder);
  1883. registerMethod("Tile", "getItemCountById", LuaScriptInterface::luaTileGetItemCountById);
  1884.  
  1885. registerMethod("Tile", "getBottomCreature", LuaScriptInterface::luaTileGetBottomCreature);
  1886. registerMethod("Tile", "getTopCreature", LuaScriptInterface::luaTileGetTopCreature);
  1887. registerMethod("Tile", "getBottomVisibleCreature", LuaScriptInterface::luaTileGetBottomVisibleCreature);
  1888. registerMethod("Tile", "getTopVisibleCreature", LuaScriptInterface::luaTileGetTopVisibleCreature);
  1889.  
  1890. registerMethod("Tile", "getItems", LuaScriptInterface::luaTileGetItems);
  1891. registerMethod("Tile", "getItemCount", LuaScriptInterface::luaTileGetItemCount);
  1892. registerMethod("Tile", "getDownItemCount", LuaScriptInterface::luaTileGetDownItemCount);
  1893. registerMethod("Tile", "getTopItemCount", LuaScriptInterface::luaTileGetTopItemCount);
  1894.  
  1895. registerMethod("Tile", "getCreatures", LuaScriptInterface::luaTileGetCreatures);
  1896. registerMethod("Tile", "getCreatureCount", LuaScriptInterface::luaTileGetCreatureCount);
  1897.  
  1898. registerMethod("Tile", "getThingIndex", LuaScriptInterface::luaTileGetThingIndex);
  1899.  
  1900. registerMethod("Tile", "hasProperty", LuaScriptInterface::luaTileHasProperty);
  1901. registerMethod("Tile", "hasFlag", LuaScriptInterface::luaTileHasFlag);
  1902.  
  1903. registerMethod("Tile", "queryAdd", LuaScriptInterface::luaTileQueryAdd);
  1904.  
  1905. registerMethod("Tile", "getHouse", LuaScriptInterface::luaTileGetHouse);
  1906.  
  1907. // NetworkMessage
  1908. registerClass("NetworkMessage", "", LuaScriptInterface::luaNetworkMessageCreate);
  1909. registerMetaMethod("NetworkMessage", "__eq", LuaScriptInterface::luaUserdataCompare);
  1910. registerMetaMethod("NetworkMessage", "__gc", LuaScriptInterface::luaNetworkMessageDelete);
  1911. registerMethod("NetworkMessage", "delete", LuaScriptInterface::luaNetworkMessageDelete);
  1912.  
  1913. registerMethod("NetworkMessage", "getByte", LuaScriptInterface::luaNetworkMessageGetByte);
  1914. registerMethod("NetworkMessage", "getU16", LuaScriptInterface::luaNetworkMessageGetU16);
  1915. registerMethod("NetworkMessage", "getU32", LuaScriptInterface::luaNetworkMessageGetU32);
  1916. registerMethod("NetworkMessage", "getU64", LuaScriptInterface::luaNetworkMessageGetU64);
  1917. registerMethod("NetworkMessage", "getString", LuaScriptInterface::luaNetworkMessageGetString);
  1918. registerMethod("NetworkMessage", "getPosition", LuaScriptInterface::luaNetworkMessageGetPosition);
  1919.  
  1920. registerMethod("NetworkMessage", "addByte", LuaScriptInterface::luaNetworkMessageAddByte);
  1921. registerMethod("NetworkMessage", "addU16", LuaScriptInterface::luaNetworkMessageAddU16);
  1922. registerMethod("NetworkMessage", "addU32", LuaScriptInterface::luaNetworkMessageAddU32);
  1923. registerMethod("NetworkMessage", "addU64", LuaScriptInterface::luaNetworkMessageAddU64);
  1924. registerMethod("NetworkMessage", "addString", LuaScriptInterface::luaNetworkMessageAddString);
  1925. registerMethod("NetworkMessage", "addPosition", LuaScriptInterface::luaNetworkMessageAddPosition);
  1926. registerMethod("NetworkMessage", "addDouble", LuaScriptInterface::luaNetworkMessageAddDouble);
  1927. registerMethod("NetworkMessage", "addItem", LuaScriptInterface::luaNetworkMessageAddItem);
  1928. registerMethod("NetworkMessage", "addItemId", LuaScriptInterface::luaNetworkMessageAddItemId);
  1929.  
  1930. registerMethod("NetworkMessage", "reset", LuaScriptInterface::luaNetworkMessageReset);
  1931. registerMethod("NetworkMessage", "skipBytes", LuaScriptInterface::luaNetworkMessageSkipBytes);
  1932. registerMethod("NetworkMessage", "sendToPlayer", LuaScriptInterface::luaNetworkMessageSendToPlayer);
  1933.  
  1934. // ModalWindow
  1935. registerClass("ModalWindow", "", LuaScriptInterface::luaModalWindowCreate);
  1936. registerMetaMethod("ModalWindow", "__eq", LuaScriptInterface::luaUserdataCompare);
  1937. registerMetaMethod("ModalWindow", "__gc", LuaScriptInterface::luaModalWindowDelete);
  1938. registerMethod("ModalWindow", "delete", LuaScriptInterface::luaModalWindowDelete);
  1939.  
  1940. registerMethod("ModalWindow", "getId", LuaScriptInterface::luaModalWindowGetId);
  1941. registerMethod("ModalWindow", "getTitle", LuaScriptInterface::luaModalWindowGetTitle);
  1942. registerMethod("ModalWindow", "getMessage", LuaScriptInterface::luaModalWindowGetMessage);
  1943.  
  1944. registerMethod("ModalWindow", "setTitle", LuaScriptInterface::luaModalWindowSetTitle);
  1945. registerMethod("ModalWindow", "setMessage", LuaScriptInterface::luaModalWindowSetMessage);
  1946.  
  1947. registerMethod("ModalWindow", "getButtonCount", LuaScriptInterface::luaModalWindowGetButtonCount);
  1948. registerMethod("ModalWindow", "getChoiceCount", LuaScriptInterface::luaModalWindowGetChoiceCount);
  1949.  
  1950. registerMethod("ModalWindow", "addButton", LuaScriptInterface::luaModalWindowAddButton);
  1951. registerMethod("ModalWindow", "addChoice", LuaScriptInterface::luaModalWindowAddChoice);
  1952.  
  1953. registerMethod("ModalWindow", "getDefaultEnterButton", LuaScriptInterface::luaModalWindowGetDefaultEnterButton);
  1954. registerMethod("ModalWindow", "setDefaultEnterButton", LuaScriptInterface::luaModalWindowSetDefaultEnterButton);
  1955.  
  1956. registerMethod("ModalWindow", "getDefaultEscapeButton", LuaScriptInterface::luaModalWindowGetDefaultEscapeButton);
  1957. registerMethod("ModalWindow", "setDefaultEscapeButton", LuaScriptInterface::luaModalWindowSetDefaultEscapeButton);
  1958.  
  1959. registerMethod("ModalWindow", "hasPriority", LuaScriptInterface::luaModalWindowHasPriority);
  1960. registerMethod("ModalWindow", "setPriority", LuaScriptInterface::luaModalWindowSetPriority);
  1961.  
  1962. registerMethod("ModalWindow", "sendToPlayer", LuaScriptInterface::luaModalWindowSendToPlayer);
  1963.  
  1964. // Item
  1965. registerClass("Item", "", LuaScriptInterface::luaItemCreate);
  1966. registerMetaMethod("Item", "__eq", LuaScriptInterface::luaUserdataCompare);
  1967.  
  1968. registerMethod("Item", "isItem", LuaScriptInterface::luaItemIsItem);
  1969.  
  1970. registerMethod("Item", "getParent", LuaScriptInterface::luaItemGetParent);
  1971. registerMethod("Item", "getTopParent", LuaScriptInterface::luaItemGetTopParent);
  1972.  
  1973. registerMethod("Item", "getId", LuaScriptInterface::luaItemGetId);
  1974.  
  1975. registerMethod("Item", "clone", LuaScriptInterface::luaItemClone);
  1976. registerMethod("Item", "split", LuaScriptInterface::luaItemSplit);
  1977. registerMethod("Item", "remove", LuaScriptInterface::luaItemRemove);
  1978.  
  1979. registerMethod("Item", "getUniqueId", LuaScriptInterface::luaItemGetUniqueId);
  1980. registerMethod("Item", "getActionId", LuaScriptInterface::luaItemGetActionId);
  1981. registerMethod("Item", "setActionId", LuaScriptInterface::luaItemSetActionId);
  1982.  
  1983. registerMethod("Item", "getCount", LuaScriptInterface::luaItemGetCount);
  1984. registerMethod("Item", "getCharges", LuaScriptInterface::luaItemGetCharges);
  1985. registerMethod("Item", "getFluidType", LuaScriptInterface::luaItemGetFluidType);
  1986. registerMethod("Item", "getWeight", LuaScriptInterface::luaItemGetWeight);
  1987.  
  1988. registerMethod("Item", "getSubType", LuaScriptInterface::luaItemGetSubType);
  1989.  
  1990. registerMethod("Item", "getName", LuaScriptInterface::luaItemGetName);
  1991. registerMethod("Item", "getPluralName", LuaScriptInterface::luaItemGetPluralName);
  1992. registerMethod("Item", "getArticle", LuaScriptInterface::luaItemGetArticle);
  1993.  
  1994. registerMethod("Item", "getPosition", LuaScriptInterface::luaItemGetPosition);
  1995. registerMethod("Item", "getTile", LuaScriptInterface::luaItemGetTile);
  1996.  
  1997. registerMethod("Item", "hasAttribute", LuaScriptInterface::luaItemHasAttribute);
  1998. registerMethod("Item", "getAttribute", LuaScriptInterface::luaItemGetAttribute);
  1999. registerMethod("Item", "setAttribute", LuaScriptInterface::luaItemSetAttribute);
  2000. registerMethod("Item", "removeAttribute", LuaScriptInterface::luaItemRemoveAttribute);
  2001. registerMethod("Item", "serializeAttributes", LuaScriptInterface::luaItemSerializeAttributes);
  2002.  
  2003. registerMethod("Item", "moveTo", LuaScriptInterface::luaItemMoveTo);
  2004. registerMethod("Item", "transform", LuaScriptInterface::luaItemTransform);
  2005. registerMethod("Item", "decay", LuaScriptInterface::luaItemDecay);
  2006.  
  2007. registerMethod("Item", "getDescription", LuaScriptInterface::luaItemGetDescription);
  2008.  
  2009. registerMethod("Item", "hasProperty", LuaScriptInterface::luaItemHasProperty);
  2010.  
  2011. // Container
  2012. registerClass("Container", "Item", LuaScriptInterface::luaContainerCreate);
  2013. registerMetaMethod("Container", "__eq", LuaScriptInterface::luaUserdataCompare);
  2014.  
  2015. registerMethod("Container", "getSize", LuaScriptInterface::luaContainerGetSize);
  2016. registerMethod("Container", "getCapacity", LuaScriptInterface::luaContainerGetCapacity);
  2017. registerMethod("Container", "getEmptySlots", LuaScriptInterface::luaContainerGetEmptySlots);
  2018.  
  2019. registerMethod("Container", "getItemHoldingCount", LuaScriptInterface::luaContainerGetItemHoldingCount);
  2020. registerMethod("Container", "getItemCountById", LuaScriptInterface::luaContainerGetItemCountById);
  2021.  
  2022. registerMethod("Container", "getItem", LuaScriptInterface::luaContainerGetItem);
  2023. registerMethod("Container", "hasItem", LuaScriptInterface::luaContainerHasItem);
  2024. registerMethod("Container", "addItem", LuaScriptInterface::luaContainerAddItem);
  2025. registerMethod("Container", "addItemEx", LuaScriptInterface::luaContainerAddItemEx);
  2026.  
  2027. // Teleport
  2028. registerClass("Teleport", "Item", LuaScriptInterface::luaTeleportCreate);
  2029. registerMetaMethod("Teleport", "__eq", LuaScriptInterface::luaUserdataCompare);
  2030.  
  2031. registerMethod("Teleport", "getDestination", LuaScriptInterface::luaTeleportGetDestination);
  2032. registerMethod("Teleport", "setDestination", LuaScriptInterface::luaTeleportSetDestination);
  2033.  
  2034. // Creature
  2035. registerClass("Creature", "", LuaScriptInterface::luaCreatureCreate);
  2036. registerMetaMethod("Creature", "__eq", LuaScriptInterface::luaUserdataCompare);
  2037.  
  2038. registerMethod("Creature", "registerEvent", LuaScriptInterface::luaCreatureRegisterEvent);
  2039. registerMethod("Creature", "unregisterEvent", LuaScriptInterface::luaCreatureUnregisterEvent);
  2040.  
  2041. registerMethod("Creature", "isRemoved", LuaScriptInterface::luaCreatureIsRemoved);
  2042. registerMethod("Creature", "isCreature", LuaScriptInterface::luaCreatureIsCreature);
  2043. registerMethod("Creature", "isInGhostMode", LuaScriptInterface::luaCreatureIsInGhostMode);
  2044. registerMethod("Creature", "isHealthHidden", LuaScriptInterface::luaCreatureIsHealthHidden);
  2045.  
  2046. registerMethod("Creature", "canSee", LuaScriptInterface::luaCreatureCanSee);
  2047. registerMethod("Creature", "canSeeCreature", LuaScriptInterface::luaCreatureCanSeeCreature);
  2048.  
  2049. registerMethod("Creature", "getParent", LuaScriptInterface::luaCreatureGetParent);
  2050.  
  2051. registerMethod("Creature", "getId", LuaScriptInterface::luaCreatureGetId);
  2052. registerMethod("Creature", "getName", LuaScriptInterface::luaCreatureGetName);
  2053.  
  2054. registerMethod("Creature", "getTarget", LuaScriptInterface::luaCreatureGetTarget);
  2055. registerMethod("Creature", "setTarget", LuaScriptInterface::luaCreatureSetTarget);
  2056.  
  2057. registerMethod("Creature", "getFollowCreature", LuaScriptInterface::luaCreatureGetFollowCreature);
  2058. registerMethod("Creature", "setFollowCreature", LuaScriptInterface::luaCreatureSetFollowCreature);
  2059.  
  2060. registerMethod("Creature", "getMaster", LuaScriptInterface::luaCreatureGetMaster);
  2061. registerMethod("Creature", "setMaster", LuaScriptInterface::luaCreatureSetMaster);
  2062.  
  2063. registerMethod("Creature", "getLight", LuaScriptInterface::luaCreatureGetLight);
  2064. registerMethod("Creature", "setLight", LuaScriptInterface::luaCreatureSetLight);
  2065.  
  2066. registerMethod("Creature", "getSpeed", LuaScriptInterface::luaCreatureGetSpeed);
  2067. registerMethod("Creature", "getBaseSpeed", LuaScriptInterface::luaCreatureGetBaseSpeed);
  2068. registerMethod("Creature", "changeSpeed", LuaScriptInterface::luaCreatureChangeSpeed);
  2069.  
  2070. registerMethod("Creature", "setDropLoot", LuaScriptInterface::luaCreatureSetDropLoot);
  2071.  
  2072. registerMethod("Creature", "getPosition", LuaScriptInterface::luaCreatureGetPosition);
  2073. registerMethod("Creature", "getTile", LuaScriptInterface::luaCreatureGetTile);
  2074. registerMethod("Creature", "getDirection", LuaScriptInterface::luaCreatureGetDirection);
  2075. registerMethod("Creature", "setDirection", LuaScriptInterface::luaCreatureSetDirection);
  2076.  
  2077. registerMethod("Creature", "getHealth", LuaScriptInterface::luaCreatureGetHealth);
  2078. registerMethod("Creature", "addHealth", LuaScriptInterface::luaCreatureAddHealth);
  2079. registerMethod("Creature", "getMaxHealth", LuaScriptInterface::luaCreatureGetMaxHealth);
  2080. registerMethod("Creature", "setMaxHealth", LuaScriptInterface::luaCreatureSetMaxHealth);
  2081. registerMethod("Creature", "setHiddenHealth", LuaScriptInterface::luaCreatureSetHiddenHealth);
  2082.  
  2083. registerMethod("Creature", "getMana", LuaScriptInterface::luaCreatureGetMana);
  2084. registerMethod("Creature", "addMana", LuaScriptInterface::luaCreatureAddMana);
  2085. registerMethod("Creature", "getMaxMana", LuaScriptInterface::luaCreatureGetMaxMana);
  2086.  
  2087. registerMethod("Creature", "getSkull", LuaScriptInterface::luaCreatureGetSkull);
  2088. registerMethod("Creature", "setSkull", LuaScriptInterface::luaCreatureSetSkull);
  2089.  
  2090. registerMethod("Creature", "getOutfit", LuaScriptInterface::luaCreatureGetOutfit);
  2091. registerMethod("Creature", "setOutfit", LuaScriptInterface::luaCreatureSetOutfit);
  2092.  
  2093. registerMethod("Creature", "getCondition", LuaScriptInterface::luaCreatureGetCondition);
  2094. registerMethod("Creature", "addCondition", LuaScriptInterface::luaCreatureAddCondition);
  2095. registerMethod("Creature", "removeCondition", LuaScriptInterface::luaCreatureRemoveCondition);
  2096.  
  2097. registerMethod("Creature", "remove", LuaScriptInterface::luaCreatureRemove);
  2098. registerMethod("Creature", "teleportTo", LuaScriptInterface::luaCreatureTeleportTo);
  2099. registerMethod("Creature", "say", LuaScriptInterface::luaCreatureSay);
  2100.  
  2101. registerMethod("Creature", "getDamageMap", LuaScriptInterface::luaCreatureGetDamageMap);
  2102.  
  2103. registerMethod("Creature", "getSummons", LuaScriptInterface::luaCreatureGetSummons);
  2104.  
  2105. registerMethod("Creature", "getDescription", LuaScriptInterface::luaCreatureGetDescription);
  2106.  
  2107. registerMethod("Creature", "getPathTo", LuaScriptInterface::luaCreatureGetPathTo);
  2108.  
  2109. // Player
  2110. registerClass("Player", "Creature", LuaScriptInterface::luaPlayerCreate);
  2111. registerMetaMethod("Player", "__eq", LuaScriptInterface::luaUserdataCompare);
  2112.  
  2113. registerMethod("Player", "isPlayer", LuaScriptInterface::luaPlayerIsPlayer);
  2114.  
  2115. registerMethod("Player", "getGuid", LuaScriptInterface::luaPlayerGetGuid);
  2116. registerMethod("Player", "getIp", LuaScriptInterface::luaPlayerGetIp);
  2117. registerMethod("Player", "getAccountId", LuaScriptInterface::luaPlayerGetAccountId);
  2118. registerMethod("Player", "getLastLoginSaved", LuaScriptInterface::luaPlayerGetLastLoginSaved);
  2119. registerMethod("Player", "getLastLogout", LuaScriptInterface::luaPlayerGetLastLogout);
  2120.  
  2121. registerMethod("Player", "getAccountType", LuaScriptInterface::luaPlayerGetAccountType);
  2122. registerMethod("Player", "setAccountType", LuaScriptInterface::luaPlayerSetAccountType);
  2123.  
  2124. registerMethod("Player", "getCapacity", LuaScriptInterface::luaPlayerGetCapacity);
  2125. registerMethod("Player", "setCapacity", LuaScriptInterface::luaPlayerSetCapacity);
  2126.  
  2127. registerMethod("Player", "getFreeCapacity", LuaScriptInterface::luaPlayerGetFreeCapacity);
  2128.  
  2129. registerMethod("Player", "getReward", LuaScriptInterface::luaPlayerGetReward);
  2130. registerMethod("Player", "removeReward", LuaScriptInterface::luaPlayerRemoveReward);
  2131. registerMethod("Player", "getRewardList", LuaScriptInterface::luaPlayerGetRewardList);
  2132.  
  2133. registerMethod("Player", "getDepotChest", LuaScriptInterface::luaPlayerGetDepotChest);
  2134. registerMethod("Player", "getInbox", LuaScriptInterface::luaPlayerGetInbox);
  2135.  
  2136. registerMethod("Player", "getSkullTime", LuaScriptInterface::luaPlayerGetSkullTime);
  2137. registerMethod("Player", "setSkullTime", LuaScriptInterface::luaPlayerSetSkullTime);
  2138. registerMethod("Player", "getDeathPenalty", LuaScriptInterface::luaPlayerGetDeathPenalty);
  2139.  
  2140. registerMethod("Player", "getExperience", LuaScriptInterface::luaPlayerGetExperience);
  2141. registerMethod("Player", "addExperience", LuaScriptInterface::luaPlayerAddExperience);
  2142. registerMethod("Player", "removeExperience", LuaScriptInterface::luaPlayerRemoveExperience);
  2143. registerMethod("Player", "getLevel", LuaScriptInterface::luaPlayerGetLevel);
  2144.  
  2145. registerMethod("Player", "getMagicLevel", LuaScriptInterface::luaPlayerGetMagicLevel);
  2146. registerMethod("Player", "getBaseMagicLevel", LuaScriptInterface::luaPlayerGetBaseMagicLevel);
  2147. registerMethod("Player", "setMaxMana", LuaScriptInterface::luaPlayerSetMaxMana);
  2148. registerMethod("Player", "getManaSpent", LuaScriptInterface::luaPlayerGetManaSpent);
  2149. registerMethod("Player", "addManaSpent", LuaScriptInterface::luaPlayerAddManaSpent);
  2150.  
  2151. registerMethod("Player", "getSkillLevel", LuaScriptInterface::luaPlayerGetSkillLevel);
  2152. registerMethod("Player", "getEffectiveSkillLevel", LuaScriptInterface::luaPlayerGetEffectiveSkillLevel);
  2153. registerMethod("Player", "getSkillPercent", LuaScriptInterface::luaPlayerGetSkillPercent);
  2154. registerMethod("Player", "getSkillTries", LuaScriptInterface::luaPlayerGetSkillTries);
  2155. registerMethod("Player", "addSkillTries", LuaScriptInterface::luaPlayerAddSkillTries);
  2156.  
  2157. registerMethod("Player", "addOfflineTrainingTime", LuaScriptInterface::luaPlayerAddOfflineTrainingTime);
  2158. registerMethod("Player", "getOfflineTrainingTime", LuaScriptInterface::luaPlayerGetOfflineTrainingTime);
  2159. registerMethod("Player", "removeOfflineTrainingTime", LuaScriptInterface::luaPlayerRemoveOfflineTrainingTime);
  2160.  
  2161. registerMethod("Player", "addOfflineTrainingTries", LuaScriptInterface::luaPlayerAddOfflineTrainingTries);
  2162.  
  2163. registerMethod("Player", "getOfflineTrainingSkill", LuaScriptInterface::luaPlayerGetOfflineTrainingSkill);
  2164. registerMethod("Player", "setOfflineTrainingSkill", LuaScriptInterface::luaPlayerSetOfflineTrainingSkill);
  2165.  
  2166. registerMethod("Player", "getItemCount", LuaScriptInterface::luaPlayerGetItemCount);
  2167. registerMethod("Player", "getItemById", LuaScriptInterface::luaPlayerGetItemById);
  2168.  
  2169. registerMethod("Player", "getVocation", LuaScriptInterface::luaPlayerGetVocation);
  2170. registerMethod("Player", "setVocation", LuaScriptInterface::luaPlayerSetVocation);
  2171.  
  2172. registerMethod("Player", "getSex", LuaScriptInterface::luaPlayerGetSex);
  2173. registerMethod("Player", "setSex", LuaScriptInterface::luaPlayerSetSex);
  2174.  
  2175. registerMethod("Player", "getTown", LuaScriptInterface::luaPlayerGetTown);
  2176. registerMethod("Player", "setTown", LuaScriptInterface::luaPlayerSetTown);
  2177.  
  2178. registerMethod("Player", "getGuild", LuaScriptInterface::luaPlayerGetGuild);
  2179. registerMethod("Player", "setGuild", LuaScriptInterface::luaPlayerSetGuild);
  2180.  
  2181. registerMethod("Player", "getGuildLevel", LuaScriptInterface::luaPlayerGetGuildLevel);
  2182. registerMethod("Player", "setGuildLevel", LuaScriptInterface::luaPlayerSetGuildLevel);
  2183.  
  2184. registerMethod("Player", "getGuildNick", LuaScriptInterface::luaPlayerGetGuildNick);
  2185. registerMethod("Player", "setGuildNick", LuaScriptInterface::luaPlayerSetGuildNick);
  2186.  
  2187. registerMethod("Player", "getGroup", LuaScriptInterface::luaPlayerGetGroup);
  2188. registerMethod("Player", "setGroup", LuaScriptInterface::luaPlayerSetGroup);
  2189.  
  2190. registerMethod("Player", "getStamina", LuaScriptInterface::luaPlayerGetStamina);
  2191. registerMethod("Player", "setStamina", LuaScriptInterface::luaPlayerSetStamina);
  2192.  
  2193. registerMethod("Player", "getSoul", LuaScriptInterface::luaPlayerGetSoul);
  2194. registerMethod("Player", "addSoul", LuaScriptInterface::luaPlayerAddSoul);
  2195. registerMethod("Player", "getMaxSoul", LuaScriptInterface::luaPlayerGetMaxSoul);
  2196.  
  2197. registerMethod("Player", "getBankBalance", LuaScriptInterface::luaPlayerGetBankBalance);
  2198. registerMethod("Player", "setBankBalance", LuaScriptInterface::luaPlayerSetBankBalance);
  2199.  
  2200. registerMethod("Player", "getStorageValue", LuaScriptInterface::luaPlayerGetStorageValue);
  2201. registerMethod("Player", "setStorageValue", LuaScriptInterface::luaPlayerSetStorageValue);
  2202.  
  2203. registerMethod("Player", "addItem", LuaScriptInterface::luaPlayerAddItem);
  2204. registerMethod("Player", "addItemEx", LuaScriptInterface::luaPlayerAddItemEx);
  2205. registerMethod("Player", "removeItem", LuaScriptInterface::luaPlayerRemoveItem);
  2206.  
  2207. registerMethod("Player", "getMoney", LuaScriptInterface::luaPlayerGetMoney);
  2208. registerMethod("Player", "addMoney", LuaScriptInterface::luaPlayerAddMoney);
  2209. registerMethod("Player", "removeMoney", LuaScriptInterface::luaPlayerRemoveMoney);
  2210.  
  2211. registerMethod("Player", "showTextDialog", LuaScriptInterface::luaPlayerShowTextDialog);
  2212.  
  2213. registerMethod("Player", "sendTextMessage", LuaScriptInterface::luaPlayerSendTextMessage);
  2214. registerMethod("Player", "sendChannelMessage", LuaScriptInterface::luaPlayerSendChannelMessage);
  2215. registerMethod("Player", "sendPrivateMessage", LuaScriptInterface::luaPlayerSendPrivateMessage);
  2216. registerMethod("Player", "channelSay", LuaScriptInterface::luaPlayerChannelSay);
  2217. registerMethod("Player", "openChannel", LuaScriptInterface::luaPlayerOpenChannel);
  2218.  
  2219. registerMethod("Player", "getSlotItem", LuaScriptInterface::luaPlayerGetSlotItem);
  2220.  
  2221. registerMethod("Player", "getParty", LuaScriptInterface::luaPlayerGetParty);
  2222.  
  2223. registerMethod("Player", "addOutfit", LuaScriptInterface::luaPlayerAddOutfit);
  2224. registerMethod("Player", "addOutfitAddon", LuaScriptInterface::luaPlayerAddOutfitAddon);
  2225. registerMethod("Player", "removeOutfit", LuaScriptInterface::luaPlayerRemoveOutfit);
  2226. registerMethod("Player", "removeOutfitAddon", LuaScriptInterface::luaPlayerRemoveOutfitAddon);
  2227. registerMethod("Player", "hasOutfit", LuaScriptInterface::luaPlayerHasOutfit);
  2228. registerMethod("Player", "sendOutfitWindow", LuaScriptInterface::luaPlayerSendOutfitWindow);
  2229.  
  2230. registerMethod("Player", "addMount", LuaScriptInterface::luaPlayerAddMount);
  2231. registerMethod("Player", "removeMount", LuaScriptInterface::luaPlayerRemoveMount);
  2232. registerMethod("Player", "hasMount", LuaScriptInterface::luaPlayerHasMount);
  2233.  
  2234. registerMethod("Player", "getPremiumDays", LuaScriptInterface::luaPlayerGetPremiumDays);
  2235. registerMethod("Player", "addPremiumDays", LuaScriptInterface::luaPlayerAddPremiumDays);
  2236. registerMethod("Player", "removePremiumDays", LuaScriptInterface::luaPlayerRemovePremiumDays);
  2237.  
  2238. registerMethod("Player", "hasBlessing", LuaScriptInterface::luaPlayerHasBlessing);
  2239. registerMethod("Player", "addBlessing", LuaScriptInterface::luaPlayerAddBlessing);
  2240. registerMethod("Player", "removeBlessing", LuaScriptInterface::luaPlayerRemoveBlessing);
  2241.  
  2242. registerMethod("Player", "canLearnSpell", LuaScriptInterface::luaPlayerCanLearnSpell);
  2243. registerMethod("Player", "learnSpell", LuaScriptInterface::luaPlayerLearnSpell);
  2244. registerMethod("Player", "forgetSpell", LuaScriptInterface::luaPlayerForgetSpell);
  2245. registerMethod("Player", "hasLearnedSpell", LuaScriptInterface::luaPlayerHasLearnedSpell);
  2246.  
  2247. registerMethod("Player", "sendTutorial", LuaScriptInterface::luaPlayerSendTutorial);
  2248. registerMethod("Player", "addMapMark", LuaScriptInterface::luaPlayerAddMapMark);
  2249.  
  2250. registerMethod("Player", "save", LuaScriptInterface::luaPlayerSave);
  2251. registerMethod("Player", "popupFYI", LuaScriptInterface::luaPlayerPopupFYI);
  2252.  
  2253. registerMethod("Player", "isPzLocked", LuaScriptInterface::luaPlayerIsPzLocked);
  2254.  
  2255. registerMethod("Player", "getClient", LuaScriptInterface::luaPlayerGetClient);
  2256. registerMethod("Player", "getHouse", LuaScriptInterface::luaPlayerGetHouse);
  2257.  
  2258. registerMethod("Player", "setGhostMode", LuaScriptInterface::luaPlayerSetGhostMode);
  2259.  
  2260. registerMethod("Player", "getContainerId", LuaScriptInterface::luaPlayerGetContainerId);
  2261. registerMethod("Player", "getContainerById", LuaScriptInterface::luaPlayerGetContainerById);
  2262. registerMethod("Player", "getContainerIndex", LuaScriptInterface::luaPlayerGetContainerIndex);
  2263.  
  2264. registerMethod("Player", "sendStoreError", LuaScriptInterface::luaPlayerSendStoreError);
  2265.  
  2266. registerMethod("Player", "startLiveCast", LuaScriptInterface::luaPlayerStartLiveCast);
  2267. registerMethod("Player", "stopLiveCast", LuaScriptInterface::luaPlayerStopLiveCast);
  2268. registerMethod("Player", "isLiveCaster", LuaScriptInterface::luaPlayerIsLiveCaster);
  2269. registerMethod("Player", "getSpectators", LuaScriptInterface::luaPlayerGetSpectators);
  2270.  
  2271. // Monster
  2272. registerClass("Monster", "Creature", LuaScriptInterface::luaMonsterCreate);
  2273. registerMetaMethod("Monster", "__eq", LuaScriptInterface::luaUserdataCompare);
  2274.  
  2275. registerMethod("Monster", "isMonster", LuaScriptInterface::luaMonsterIsMonster);
  2276.  
  2277. registerMethod("Monster", "getType", LuaScriptInterface::luaMonsterGetType);
  2278.  
  2279. registerMethod("Monster", "getSpawnPosition", LuaScriptInterface::luaMonsterGetSpawnPosition);
  2280. registerMethod("Monster", "isInSpawnRange", LuaScriptInterface::luaMonsterIsInSpawnRange);
  2281.  
  2282. registerMethod("Monster", "isIdle", LuaScriptInterface::luaMonsterIsIdle);
  2283. registerMethod("Monster", "setIdle", LuaScriptInterface::luaMonsterSetIdle);
  2284.  
  2285. registerMethod("Monster", "isTarget", LuaScriptInterface::luaMonsterIsTarget);
  2286. registerMethod("Monster", "isOpponent", LuaScriptInterface::luaMonsterIsOpponent);
  2287. registerMethod("Monster", "isFriend", LuaScriptInterface::luaMonsterIsFriend);
  2288.  
  2289. registerMethod("Monster", "addFriend", LuaScriptInterface::luaMonsterAddFriend);
  2290. registerMethod("Monster", "removeFriend", LuaScriptInterface::luaMonsterRemoveFriend);
  2291. registerMethod("Monster", "getFriendList", LuaScriptInterface::luaMonsterGetFriendList);
  2292. registerMethod("Monster", "getFriendCount", LuaScriptInterface::luaMonsterGetFriendCount);
  2293.  
  2294. registerMethod("Monster", "addTarget", LuaScriptInterface::luaMonsterAddTarget);
  2295. registerMethod("Monster", "removeTarget", LuaScriptInterface::luaMonsterRemoveTarget);
  2296. registerMethod("Monster", "getTargetList", LuaScriptInterface::luaMonsterGetTargetList);
  2297. registerMethod("Monster", "getTargetCount", LuaScriptInterface::luaMonsterGetTargetCount);
  2298.  
  2299. registerMethod("Monster", "selectTarget", LuaScriptInterface::luaMonsterSelectTarget);
  2300. registerMethod("Monster", "searchTarget", LuaScriptInterface::luaMonsterSearchTarget);
  2301.  
  2302. // Npc
  2303. registerClass("Npc", "Creature", LuaScriptInterface::luaNpcCreate);
  2304. registerMetaMethod("Npc", "__eq", LuaScriptInterface::luaUserdataCompare);
  2305.  
  2306. registerMethod("Npc", "isNpc", LuaScriptInterface::luaNpcIsNpc);
  2307.  
  2308. registerMethod("Npc", "setMasterPos", LuaScriptInterface::luaNpcSetMasterPos);
  2309.  
  2310. registerMethod("Npc", "getSpeechBubble", LuaScriptInterface::luaNpcGetSpeechBubble);
  2311. registerMethod("Npc", "setSpeechBubble", LuaScriptInterface::luaNpcSetSpeechBubble);
  2312.  
  2313. // Guild
  2314. registerClass("Guild", "", LuaScriptInterface::luaGuildCreate);
  2315. registerMetaMethod("Guild", "__eq", LuaScriptInterface::luaUserdataCompare);
  2316.  
  2317. registerMethod("Guild", "getId", LuaScriptInterface::luaGuildGetId);
  2318. registerMethod("Guild", "getName", LuaScriptInterface::luaGuildGetName);
  2319. registerMethod("Guild", "getMembersOnline", LuaScriptInterface::luaGuildGetMembersOnline);
  2320. registerMethod("Guild", "getBankBalance", LuaScriptInterface::luaGuildGetBankBalance);
  2321. registerMethod("Guild", "setBankBalance", LuaScriptInterface::luaGuildSetBankBalance);
  2322.  
  2323. registerMethod("Guild", "addRank", LuaScriptInterface::luaGuildAddRank);
  2324. registerMethod("Guild", "getRankById", LuaScriptInterface::luaGuildGetRankById);
  2325. registerMethod("Guild", "getRankByLevel", LuaScriptInterface::luaGuildGetRankByLevel);
  2326.  
  2327. registerMethod("Guild", "getMotd", LuaScriptInterface::luaGuildGetMotd);
  2328. registerMethod("Guild", "setMotd", LuaScriptInterface::luaGuildSetMotd);
  2329.  
  2330. // Group
  2331. registerClass("Group", "", LuaScriptInterface::luaGroupCreate);
  2332. registerMetaMethod("Group", "__eq", LuaScriptInterface::luaUserdataCompare);
  2333.  
  2334. registerMethod("Group", "getId", LuaScriptInterface::luaGroupGetId);
  2335. registerMethod("Group", "getName", LuaScriptInterface::luaGroupGetName);
  2336. registerMethod("Group", "getFlags", LuaScriptInterface::luaGroupGetFlags);
  2337. registerMethod("Group", "getAccess", LuaScriptInterface::luaGroupGetAccess);
  2338. registerMethod("Group", "getMaxDepotItems", LuaScriptInterface::luaGroupGetMaxDepotItems);
  2339. registerMethod("Group", "getMaxVipEntries", LuaScriptInterface::luaGroupGetMaxVipEntries);
  2340.  
  2341. // Vocation
  2342. registerClass("Vocation", "", LuaScriptInterface::luaVocationCreate);
  2343. registerMetaMethod("Vocation", "__eq", LuaScriptInterface::luaUserdataCompare);
  2344.  
  2345. registerMethod("Vocation", "getId", LuaScriptInterface::luaVocationGetId);
  2346. registerMethod("Vocation", "getClientId", LuaScriptInterface::luaVocationGetClientId);
  2347. registerMethod("Vocation", "getName", LuaScriptInterface::luaVocationGetName);
  2348. registerMethod("Vocation", "getDescription", LuaScriptInterface::luaVocationGetDescription);
  2349.  
  2350. registerMethod("Vocation", "getRequiredSkillTries", LuaScriptInterface::luaVocationGetRequiredSkillTries);
  2351. registerMethod("Vocation", "getRequiredManaSpent", LuaScriptInterface::luaVocationGetRequiredManaSpent);
  2352.  
  2353. registerMethod("Vocation", "getCapacityGain", LuaScriptInterface::luaVocationGetCapacityGain);
  2354.  
  2355. registerMethod("Vocation", "getHealthGain", LuaScriptInterface::luaVocationGetHealthGain);
  2356. registerMethod("Vocation", "getHealthGainTicks", LuaScriptInterface::luaVocationGetHealthGainTicks);
  2357. registerMethod("Vocation", "getHealthGainAmount", LuaScriptInterface::luaVocationGetHealthGainAmount);
  2358.  
  2359. registerMethod("Vocation", "getManaGain", LuaScriptInterface::luaVocationGetManaGain);
  2360. registerMethod("Vocation", "getManaGainTicks", LuaScriptInterface::luaVocationGetManaGainTicks);
  2361. registerMethod("Vocation", "getManaGainAmount", LuaScriptInterface::luaVocationGetManaGainAmount);
  2362.  
  2363. registerMethod("Vocation", "getMaxSoul", LuaScriptInterface::luaVocationGetMaxSoul);
  2364. registerMethod("Vocation", "getSoulGainTicks", LuaScriptInterface::luaVocationGetSoulGainTicks);
  2365.  
  2366. registerMethod("Vocation", "getAttackSpeed", LuaScriptInterface::luaVocationGetAttackSpeed);
  2367. registerMethod("Vocation", "getBaseSpeed", LuaScriptInterface::luaVocationGetBaseSpeed);
  2368.  
  2369. registerMethod("Vocation", "getDemotion", LuaScriptInterface::luaVocationGetDemotion);
  2370. registerMethod("Vocation", "getPromotion", LuaScriptInterface::luaVocationGetPromotion);
  2371.  
  2372. // Town
  2373. registerClass("Town", "", LuaScriptInterface::luaTownCreate);
  2374. registerMetaMethod("Town", "__eq", LuaScriptInterface::luaUserdataCompare);
  2375.  
  2376. registerMethod("Town", "getId", LuaScriptInterface::luaTownGetId);
  2377. registerMethod("Town", "getName", LuaScriptInterface::luaTownGetName);
  2378. registerMethod("Town", "getTemplePosition", LuaScriptInterface::luaTownGetTemplePosition);
  2379.  
  2380. // House
  2381. registerClass("House", "", LuaScriptInterface::luaHouseCreate);
  2382. registerMetaMethod("House", "__eq", LuaScriptInterface::luaUserdataCompare);
  2383.  
  2384. registerMethod("House", "getId", LuaScriptInterface::luaHouseGetId);
  2385. registerMethod("House", "getName", LuaScriptInterface::luaHouseGetName);
  2386. registerMethod("House", "getTown", LuaScriptInterface::luaHouseGetTown);
  2387. registerMethod("House", "getExitPosition", LuaScriptInterface::luaHouseGetExitPosition);
  2388. registerMethod("House", "getRent", LuaScriptInterface::luaHouseGetRent);
  2389.  
  2390. registerMethod("House", "getOwnerGuid", LuaScriptInterface::luaHouseGetOwnerGuid);
  2391. registerMethod("House", "setOwnerGuid", LuaScriptInterface::luaHouseSetOwnerGuid);
  2392.  
  2393. registerMethod("House", "getBeds", LuaScriptInterface::luaHouseGetBeds);
  2394. registerMethod("House", "getBedCount", LuaScriptInterface::luaHouseGetBedCount);
  2395.  
  2396. registerMethod("House", "getDoors", LuaScriptInterface::luaHouseGetDoors);
  2397. registerMethod("House", "getDoorCount", LuaScriptInterface::luaHouseGetDoorCount);
  2398.  
  2399. registerMethod("House", "getTiles", LuaScriptInterface::luaHouseGetTiles);
  2400. registerMethod("House", "getTileCount", LuaScriptInterface::luaHouseGetTileCount);
  2401.  
  2402. registerMethod("House", "getAccessList", LuaScriptInterface::luaHouseGetAccessList);
  2403. registerMethod("House", "setAccessList", LuaScriptInterface::luaHouseSetAccessList);
  2404.  
  2405. // ItemType
  2406. registerClass("ItemType", "", LuaScriptInterface::luaItemTypeCreate);
  2407. registerMetaMethod("ItemType", "__eq", LuaScriptInterface::luaUserdataCompare);
  2408.  
  2409. registerMethod("ItemType", "isCorpse", LuaScriptInterface::luaItemTypeIsCorpse);
  2410. registerMethod("ItemType", "isDoor", LuaScriptInterface::luaItemTypeIsDoor);
  2411. registerMethod("ItemType", "isContainer", LuaScriptInterface::luaItemTypeIsContainer);
  2412. registerMethod("ItemType", "isFluidContainer", LuaScriptInterface::luaItemTypeIsFluidContainer);
  2413. registerMethod("ItemType", "isMovable", LuaScriptInterface::luaItemTypeIsMovable);
  2414. registerMethod("ItemType", "isRune", LuaScriptInterface::luaItemTypeIsRune);
  2415. registerMethod("ItemType", "isStackable", LuaScriptInterface::luaItemTypeIsStackable);
  2416. registerMethod("ItemType", "isReadable", LuaScriptInterface::luaItemTypeIsReadable);
  2417. registerMethod("ItemType", "isWritable", LuaScriptInterface::luaItemTypeIsWritable);
  2418.  
  2419. registerMethod("ItemType", "getType", LuaScriptInterface::luaItemTypeGetType);
  2420. registerMethod("ItemType", "getId", LuaScriptInterface::luaItemTypeGetId);
  2421. registerMethod("ItemType", "getClientId", LuaScriptInterface::luaItemTypeGetClientId);
  2422. registerMethod("ItemType", "getName", LuaScriptInterface::luaItemTypeGetName);
  2423. registerMethod("ItemType", "getPluralName", LuaScriptInterface::luaItemTypeGetPluralName);
  2424. registerMethod("ItemType", "getArticle", LuaScriptInterface::luaItemTypeGetArticle);
  2425. registerMethod("ItemType", "getDescription", LuaScriptInterface::luaItemTypeGetDescription);
  2426. registerMethod("ItemType", "getSlotPosition", LuaScriptInterface::luaItemTypeGetSlotPosition);
  2427.  
  2428. registerMethod("ItemType", "getCharges", LuaScriptInterface::luaItemTypeGetCharges);
  2429. registerMethod("ItemType", "getFluidSource", LuaScriptInterface::luaItemTypeGetFluidSource);
  2430. registerMethod("ItemType", "getCapacity", LuaScriptInterface::luaItemTypeGetCapacity);
  2431. registerMethod("ItemType", "getWeight", LuaScriptInterface::luaItemTypeGetWeight);
  2432.  
  2433. registerMethod("ItemType", "getHitChance", LuaScriptInterface::luaItemTypeGetHitChance);
  2434. registerMethod("ItemType", "getShootRange", LuaScriptInterface::luaItemTypeGetShootRange);
  2435.  
  2436. registerMethod("ItemType", "getAttack", LuaScriptInterface::luaItemTypeGetAttack);
  2437. registerMethod("ItemType", "getDefense", LuaScriptInterface::luaItemTypeGetDefense);
  2438. registerMethod("ItemType", "getExtraDefense", LuaScriptInterface::luaItemTypeGetExtraDefense);
  2439. registerMethod("ItemType", "getArmor", LuaScriptInterface::luaItemTypeGetArmor);
  2440. registerMethod("ItemType", "getWeaponType", LuaScriptInterface::luaItemTypeGetWeaponType);
  2441.  
  2442. registerMethod("ItemType", "getElementType", LuaScriptInterface::luaItemTypeGetElementType);
  2443. registerMethod("ItemType", "getElementDamage", LuaScriptInterface::luaItemTypeGetElementDamage);
  2444.  
  2445. registerMethod("ItemType", "getTransformEquipId", LuaScriptInterface::luaItemTypeGetTransformEquipId);
  2446. registerMethod("ItemType", "getTransformDeEquipId", LuaScriptInterface::luaItemTypeGetTransformDeEquipId);
  2447. registerMethod("ItemType", "getDestroyId", LuaScriptInterface::luaItemTypeGetDestroyId);
  2448. registerMethod("ItemType", "getDecayId", LuaScriptInterface::luaItemTypeGetDecayId);
  2449. registerMethod("ItemType", "getRequiredLevel", LuaScriptInterface::luaItemTypeGetRequiredLevel);
  2450.  
  2451. registerMethod("ItemType", "hasSubType", LuaScriptInterface::luaItemTypeHasSubType);
  2452.  
  2453. // Combat
  2454. registerClass("Combat", "", LuaScriptInterface::luaCombatCreate);
  2455. registerMetaMethod("Combat", "__eq", LuaScriptInterface::luaUserdataCompare);
  2456.  
  2457. registerMethod("Combat", "setParameter", LuaScriptInterface::luaCombatSetParameter);
  2458. registerMethod("Combat", "setFormula", LuaScriptInterface::luaCombatSetFormula);
  2459.  
  2460. registerMethod("Combat", "setArea", LuaScriptInterface::luaCombatSetArea);
  2461. registerMethod("Combat", "setCondition", LuaScriptInterface::luaCombatSetCondition);
  2462. registerMethod("Combat", "setCallback", LuaScriptInterface::luaCombatSetCallback);
  2463. registerMethod("Combat", "setOrigin", LuaScriptInterface::luaCombatSetOrigin);
  2464.  
  2465. registerMethod("Combat", "execute", LuaScriptInterface::luaCombatExecute);
  2466.  
  2467. // Condition
  2468. registerClass("Condition", "", LuaScriptInterface::luaConditionCreate);
  2469. registerMetaMethod("Condition", "__eq", LuaScriptInterface::luaUserdataCompare);
  2470. registerMetaMethod("Condition", "__gc", LuaScriptInterface::luaConditionDelete);
  2471. registerMethod("Condition", "delete", LuaScriptInterface::luaConditionDelete);
  2472.  
  2473. registerMethod("Condition", "getId", LuaScriptInterface::luaConditionGetId);
  2474. registerMethod("Condition", "getSubId", LuaScriptInterface::luaConditionGetSubId);
  2475. registerMethod("Condition", "getType", LuaScriptInterface::luaConditionGetType);
  2476. registerMethod("Condition", "getIcons", LuaScriptInterface::luaConditionGetIcons);
  2477. registerMethod("Condition", "getEndTime", LuaScriptInterface::luaConditionGetEndTime);
  2478.  
  2479. registerMethod("Condition", "clone", LuaScriptInterface::luaConditionClone);
  2480.  
  2481. registerMethod("Condition", "getTicks", LuaScriptInterface::luaConditionGetTicks);
  2482. registerMethod("Condition", "setTicks", LuaScriptInterface::luaConditionSetTicks);
  2483.  
  2484. registerMethod("Condition", "setParameter", LuaScriptInterface::luaConditionSetParameter);
  2485. registerMethod("Condition", "setFormula", LuaScriptInterface::luaConditionSetFormula);
  2486. registerMethod("Condition", "setOutfit", LuaScriptInterface::luaConditionSetOutfit);
  2487.  
  2488. registerMethod("Condition", "addDamage", LuaScriptInterface::luaConditionAddDamage);
  2489.  
  2490. // MonsterType
  2491. registerClass("MonsterType", "", LuaScriptInterface::luaMonsterTypeCreate);
  2492. registerMetaMethod("MonsterType", "__eq", LuaScriptInterface::luaUserdataCompare);
  2493.  
  2494. registerMethod("MonsterType", "isAttackable", LuaScriptInterface::luaMonsterTypeIsAttackable);
  2495. registerMethod("MonsterType", "isConvinceable", LuaScriptInterface::luaMonsterTypeIsConvinceable);
  2496. registerMethod("MonsterType", "isSummonable", LuaScriptInterface::luaMonsterTypeIsSummonable);
  2497. registerMethod("MonsterType", "isIllusionable", LuaScriptInterface::luaMonsterTypeIsIllusionable);
  2498. registerMethod("MonsterType", "isHostile", LuaScriptInterface::luaMonsterTypeIsHostile);
  2499. registerMethod("MonsterType", "isPushable", LuaScriptInterface::luaMonsterTypeIsPushable);
  2500. registerMethod("MonsterType", "isHealthShown", LuaScriptInterface::luaMonsterTypeIsHealthShown);
  2501. registerMethod("MonsterType", "isRewardBoss", LuaScriptInterface::luaMonsterTypeIsRewardBoss);
  2502.  
  2503. registerMethod("MonsterType", "canPushItems", LuaScriptInterface::luaMonsterTypeCanPushItems);
  2504. registerMethod("MonsterType", "canPushCreatures", LuaScriptInterface::luaMonsterTypeCanPushCreatures);
  2505.  
  2506. registerMethod("MonsterType", "getName", LuaScriptInterface::luaMonsterTypeGetName);
  2507. registerMethod("MonsterType", "getNameDescription", LuaScriptInterface::luaMonsterTypeGetNameDescription);
  2508.  
  2509. registerMethod("MonsterType", "getHealth", LuaScriptInterface::luaMonsterTypeGetHealth);
  2510. registerMethod("MonsterType", "getMaxHealth", LuaScriptInterface::luaMonsterTypeGetMaxHealth);
  2511. registerMethod("MonsterType", "getRunHealth", LuaScriptInterface::luaMonsterTypeGetRunHealth);
  2512. registerMethod("MonsterType", "getExperience", LuaScriptInterface::luaMonsterTypeGetExperience);
  2513.  
  2514. registerMethod("MonsterType", "getCombatImmunities", LuaScriptInterface::luaMonsterTypeGetCombatImmunities);
  2515. registerMethod("MonsterType", "getConditionImmunities", LuaScriptInterface::luaMonsterTypeGetConditionImmunities);
  2516.  
  2517. registerMethod("MonsterType", "getAttackList", LuaScriptInterface::luaMonsterTypeGetAttackList);
  2518. registerMethod("MonsterType", "getDefenseList", LuaScriptInterface::luaMonsterTypeGetDefenseList);
  2519. registerMethod("MonsterType", "getElementList", LuaScriptInterface::luaMonsterTypeGetElementList);
  2520.  
  2521. registerMethod("MonsterType", "getVoices", LuaScriptInterface::luaMonsterTypeGetVoices);
  2522. registerMethod("MonsterType", "getLoot", LuaScriptInterface::luaMonsterTypeGetLoot);
  2523. registerMethod("MonsterType", "getCreatureEvents", LuaScriptInterface::luaMonsterTypeGetCreatureEvents);
  2524.  
  2525. registerMethod("MonsterType", "getSummonList", LuaScriptInterface::luaMonsterTypeGetSummonList);
  2526. registerMethod("MonsterType", "getMaxSummons", LuaScriptInterface::luaMonsterTypeGetMaxSummons);
  2527.  
  2528. registerMethod("MonsterType", "getArmor", LuaScriptInterface::luaMonsterTypeGetArmor);
  2529. registerMethod("MonsterType", "getDefense", LuaScriptInterface::luaMonsterTypeGetDefense);
  2530. registerMethod("MonsterType", "getOutfit", LuaScriptInterface::luaMonsterTypeGetOutfit);
  2531. registerMethod("MonsterType", "getRace", LuaScriptInterface::luaMonsterTypeGetRace);
  2532. registerMethod("MonsterType", "getCorpseId", LuaScriptInterface::luaMonsterTypeGetCorpseId);
  2533. registerMethod("MonsterType", "getManaCost", LuaScriptInterface::luaMonsterTypeGetManaCost);
  2534. registerMethod("MonsterType", "getBaseSpeed", LuaScriptInterface::luaMonsterTypeGetBaseSpeed);
  2535. registerMethod("MonsterType", "getLight", LuaScriptInterface::luaMonsterTypeGetLight);
  2536.  
  2537. registerMethod("MonsterType", "getStaticAttackChance", LuaScriptInterface::luaMonsterTypeGetStaticAttackChance);
  2538. registerMethod("MonsterType", "getTargetDistance", LuaScriptInterface::luaMonsterTypeGetTargetDistance);
  2539. registerMethod("MonsterType", "getYellChance", LuaScriptInterface::luaMonsterTypeGetYellChance);
  2540. registerMethod("MonsterType", "getYellSpeedTicks", LuaScriptInterface::luaMonsterTypeGetYellSpeedTicks);
  2541. registerMethod("MonsterType", "getChangeTargetChance", LuaScriptInterface::luaMonsterTypeGetChangeTargetChance);
  2542. registerMethod("MonsterType", "getChangeTargetSpeed", LuaScriptInterface::luaMonsterTypeGetChangeTargetSpeed);
  2543.  
  2544. // Party
  2545. registerClass("Party", "", nullptr);
  2546. registerMetaMethod("Party", "__eq", LuaScriptInterface::luaUserdataCompare);
  2547.  
  2548. registerMethod("Party", "disband", LuaScriptInterface::luaPartyDisband);
  2549.  
  2550. registerMethod("Party", "getLeader", LuaScriptInterface::luaPartyGetLeader);
  2551. registerMethod("Party", "setLeader", LuaScriptInterface::luaPartySetLeader);
  2552.  
  2553. registerMethod("Party", "getMembers", LuaScriptInterface::luaPartyGetMembers);
  2554. registerMethod("Party", "getMemberCount", LuaScriptInterface::luaPartyGetMemberCount);
  2555.  
  2556. registerMethod("Party", "getInvitees", LuaScriptInterface::luaPartyGetInvitees);
  2557. registerMethod("Party", "getInviteeCount", LuaScriptInterface::luaPartyGetInviteeCount);
  2558.  
  2559. registerMethod("Party", "addInvite", LuaScriptInterface::luaPartyAddInvite);
  2560. registerMethod("Party", "removeInvite", LuaScriptInterface::luaPartyRemoveInvite);
  2561.  
  2562. registerMethod("Party", "addMember", LuaScriptInterface::luaPartyAddMember);
  2563. registerMethod("Party", "removeMember", LuaScriptInterface::luaPartyRemoveMember);
  2564.  
  2565. registerMethod("Party", "isSharedExperienceActive", LuaScriptInterface::luaPartyIsSharedExperienceActive);
  2566. registerMethod("Party", "isSharedExperienceEnabled", LuaScriptInterface::luaPartyIsSharedExperienceEnabled);
  2567. registerMethod("Party", "shareExperience", LuaScriptInterface::luaPartyShareExperience);
  2568. registerMethod("Party", "setSharedExperience", LuaScriptInterface::luaPartySetSharedExperience);
  2569.  
  2570. // StoreOffer
  2571. registerClass("StoreOffer", "", LuaScriptInterface::luaStoreOfferCreate);
  2572. registerMetaMethod("StoreOffer", "__eq", LuaScriptInterface::luaUserdataCompare);
  2573.  
  2574. registerMethod("StoreOffer", "getId", LuaScriptInterface::luaStoreOfferGetId);
  2575. registerMethod("StoreOffer", "getName", LuaScriptInterface::luaStoreOfferGetName);
  2576. }
  2577.  
  2578. #undef registerEnum
  2579. #undef registerEnumIn
  2580.  
  2581. void LuaScriptInterface::registerClass(const std::string& className, const std::string& baseClass, lua_CFunction newFunction/* = nullptr*/)
  2582. {
  2583. // className = {}
  2584. lua_newtable(m_luaState);
  2585. lua_pushvalue(m_luaState, -1);
  2586. lua_setglobal(m_luaState, className.c_str());
  2587. int methods = lua_gettop(m_luaState);
  2588.  
  2589. // methodsTable = {}
  2590. lua_newtable(m_luaState);
  2591. int methodsTable = lua_gettop(m_luaState);
  2592.  
  2593. if (newFunction) {
  2594. // className.__call = newFunction
  2595. lua_pushcfunction(m_luaState, newFunction);
  2596. lua_setfield(m_luaState, methodsTable, "__call");
  2597. }
  2598.  
  2599. uint32_t parents = 0;
  2600. if (!baseClass.empty()) {
  2601. lua_getglobal(m_luaState, baseClass.c_str());
  2602. lua_rawgeti(m_luaState, -1, 'p');
  2603. parents = getNumber<uint32_t>(m_luaState, -1) + 1;
  2604. lua_pop(m_luaState, 1);
  2605. lua_setfield(m_luaState, methodsTable, "__index");
  2606. }
  2607.  
  2608. // setmetatable(className, methodsTable)
  2609. lua_setmetatable(m_luaState, methods);
  2610.  
  2611. // className.metatable = {}
  2612. luaL_newmetatable(m_luaState, className.c_str());
  2613. int metatable = lua_gettop(m_luaState);
  2614.  
  2615. // className.metatable.__metatable = className
  2616. lua_pushvalue(m_luaState, methods);
  2617. lua_setfield(m_luaState, metatable, "__metatable");
  2618.  
  2619. // className.metatable.__index = className
  2620. lua_pushvalue(m_luaState, methods);
  2621. lua_setfield(m_luaState, metatable, "__index");
  2622.  
  2623. // className.metatable['h'] = hash
  2624. lua_pushnumber(m_luaState, std::hash<std::string>()(className));
  2625. lua_rawseti(m_luaState, metatable, 'h');
  2626.  
  2627. // className.metatable['p'] = parents
  2628. lua_pushnumber(m_luaState, parents);
  2629. lua_rawseti(m_luaState, metatable, 'p');
  2630.  
  2631. // className.metatable['t'] = type
  2632. if (className == "Item") {
  2633. lua_pushnumber(m_luaState, LuaData_Item);
  2634. } else if (className == "Container") {
  2635. lua_pushnumber(m_luaState, LuaData_Container);
  2636. } else if (className == "Teleport") {
  2637. lua_pushnumber(m_luaState, LuaData_Teleport);
  2638. } else if (className == "Player") {
  2639. lua_pushnumber(m_luaState, LuaData_Player);
  2640. } else if (className == "Monster") {
  2641. lua_pushnumber(m_luaState, LuaData_Monster);
  2642. } else if (className == "Npc") {
  2643. lua_pushnumber(m_luaState, LuaData_Npc);
  2644. } else if (className == "Tile") {
  2645. lua_pushnumber(m_luaState, LuaData_Tile);
  2646. } else {
  2647. lua_pushnumber(m_luaState, LuaData_Unknown);
  2648. }
  2649. lua_rawseti(m_luaState, metatable, 't');
  2650.  
  2651. // pop className, className.metatable
  2652. lua_pop(m_luaState, 2);
  2653. }
  2654.  
  2655. void LuaScriptInterface::registerTable(const std::string& tableName)
  2656. {
  2657. // _G[tableName] = {}
  2658. lua_newtable(m_luaState);
  2659. lua_setglobal(m_luaState, tableName.c_str());
  2660. }
  2661.  
  2662. void LuaScriptInterface::registerMethod(const std::string& globalName, const std::string& methodName, lua_CFunction func)
  2663. {
  2664. // globalName.methodName = func
  2665. lua_getglobal(m_luaState, globalName.c_str());
  2666. lua_pushcfunction(m_luaState, func);
  2667. lua_setfield(m_luaState, -2, methodName.c_str());
  2668.  
  2669. // pop globalName
  2670. lua_pop(m_luaState, 1);
  2671. }
  2672.  
  2673. void LuaScriptInterface::registerMetaMethod(const std::string& className, const std::string& methodName, lua_CFunction func)
  2674. {
  2675. // className.metatable.methodName = func
  2676. luaL_getmetatable(m_luaState, className.c_str());
  2677. lua_pushcfunction(m_luaState, func);
  2678. lua_setfield(m_luaState, -2, methodName.c_str());
  2679.  
  2680. // pop className.metatable
  2681. lua_pop(m_luaState, 1);
  2682. }
  2683.  
  2684. void LuaScriptInterface::registerGlobalMethod(const std::string& functionName, lua_CFunction func)
  2685. {
  2686. // _G[functionName] = func
  2687. lua_pushcfunction(m_luaState, func);
  2688. lua_setglobal(m_luaState, functionName.c_str());
  2689. }
  2690.  
  2691. void LuaScriptInterface::registerVariable(const std::string& tableName, const std::string& name, lua_Number value)
  2692. {
  2693. // tableName.name = value
  2694. lua_getglobal(m_luaState, tableName.c_str());
  2695. setField(m_luaState, name.c_str(), value);
  2696.  
  2697. // pop tableName
  2698. lua_pop(m_luaState, 1);
  2699. }
  2700.  
  2701. void LuaScriptInterface::registerGlobalVariable(const std::string& name, lua_Number value)
  2702. {
  2703. // _G[name] = value
  2704. lua_pushnumber(m_luaState, value);
  2705. lua_setglobal(m_luaState, name.c_str());
  2706. }
  2707.  
  2708. void LuaScriptInterface::registerGlobalBoolean(const std::string& name, bool value)
  2709. {
  2710. // _G[name] = value
  2711. pushBoolean(m_luaState, value);
  2712. lua_setglobal(m_luaState, name.c_str());
  2713. }
  2714.  
  2715. int LuaScriptInterface::luaGetPlayerFlagValue(lua_State* L)
  2716. {
  2717. //getPlayerFlagValue(cid, flag)
  2718. Player* player = getPlayer(L, 1);
  2719. if (player) {
  2720. PlayerFlags flag = getNumber<PlayerFlags>(L, 2);
  2721. pushBoolean(L, player->hasFlag(flag));
  2722. } else {
  2723. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2724. pushBoolean(L, false);
  2725. }
  2726. return 1;
  2727. }
  2728.  
  2729. int LuaScriptInterface::luaGetPlayerInstantSpellCount(lua_State* L)
  2730. {
  2731. //getPlayerInstantSpellCount(cid)
  2732. Player* player = getPlayer(L, 1);
  2733. if (player) {
  2734. lua_pushnumber(L, g_spells->getInstantSpellCount(player));
  2735. } else {
  2736. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2737. pushBoolean(L, false);
  2738. }
  2739. return 1;
  2740. }
  2741.  
  2742. int LuaScriptInterface::luaGetPlayerInstantSpellInfo(lua_State* L)
  2743. {
  2744. //getPlayerInstantSpellInfo(cid, index)
  2745. Player* player = getPlayer(L, 1);
  2746. if (!player) {
  2747. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2748. pushBoolean(L, false);
  2749. return 1;
  2750. }
  2751.  
  2752. uint32_t index = getNumber<uint32_t>(L, 2);
  2753. InstantSpell* spell = g_spells->getInstantSpellByIndex(player, index);
  2754. if (!spell) {
  2755. reportErrorFunc(getErrorDesc(LUA_ERROR_SPELL_NOT_FOUND));
  2756. pushBoolean(L, false);
  2757. return 1;
  2758. }
  2759.  
  2760. lua_createtable(L, 0, 6);
  2761. setField(L, "name", spell->getName());
  2762. setField(L, "words", spell->getWords());
  2763. setField(L, "level", spell->getLevel());
  2764. setField(L, "mlevel", spell->getMagicLevel());
  2765. setField(L, "mana", spell->getManaCost(player));
  2766. setField(L, "manapercent", spell->getManaPercent());
  2767. return 1;
  2768. }
  2769.  
  2770. int LuaScriptInterface::luaDoPlayerAddItem(lua_State* L)
  2771. {
  2772. //doPlayerAddItem(cid, itemid, <optional: default: 1> count/subtype, <optional: default: 1> canDropOnMap)
  2773. //doPlayerAddItem(cid, itemid, <optional: default: 1> count, <optional: default: 1> canDropOnMap, <optional: default: 1>subtype)
  2774. Player* player = getPlayer(L, 1);
  2775. if (!player) {
  2776. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2777. pushBoolean(L, false);
  2778. return 1;
  2779. }
  2780.  
  2781. uint16_t itemId = getNumber<uint16_t>(L, 2);
  2782. int32_t count = getNumber<int32_t>(L, 3, 1);
  2783. bool canDropOnMap = getBoolean(L, 4, true);
  2784. uint16_t subType = getNumber<uint16_t>(L, 5, 1);
  2785.  
  2786. const ItemType& it = Item::items[itemId];
  2787. int32_t itemCount;
  2788.  
  2789. auto parameters = lua_gettop(L);
  2790. if (parameters > 4) {
  2791. //subtype already supplied, count then is the amount
  2792. itemCount = std::max<int32_t>(1, count);
  2793. } else if (it.hasSubType()) {
  2794. if (it.stackable) {
  2795. itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
  2796. } else {
  2797. itemCount = 1;
  2798. }
  2799. subType = count;
  2800. } else {
  2801. itemCount = std::max<int32_t>(1, count);
  2802. }
  2803.  
  2804. while (itemCount > 0) {
  2805. uint16_t stackCount = subType;
  2806. if (it.stackable && stackCount > 100) {
  2807. stackCount = 100;
  2808. }
  2809.  
  2810. Item* newItem = Item::CreateItem(itemId, stackCount);
  2811. if (!newItem) {
  2812. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2813. pushBoolean(L, false);
  2814. return 1;
  2815. }
  2816.  
  2817. if (it.stackable) {
  2818. subType -= stackCount;
  2819. }
  2820.  
  2821. ReturnValue ret = g_game.internalPlayerAddItem(player, newItem, canDropOnMap);
  2822. if (ret != RETURNVALUE_NOERROR) {
  2823. delete newItem;
  2824. pushBoolean(L, false);
  2825. return 1;
  2826. }
  2827.  
  2828. if (--itemCount == 0) {
  2829. if (newItem->getParent()) {
  2830. uint32_t uid = getScriptEnv()->addThing(newItem);
  2831. lua_pushnumber(L, uid);
  2832. return 1;
  2833. } else {
  2834. //stackable item stacked with existing object, newItem will be released
  2835. pushBoolean(L, false);
  2836. return 1;
  2837. }
  2838. }
  2839. }
  2840.  
  2841. pushBoolean(L, false);
  2842. return 1;
  2843. }
  2844.  
  2845. int LuaScriptInterface::luaDoTileAddItemEx(lua_State* L)
  2846. {
  2847. //doTileAddItemEx(pos, uid)
  2848. const Position& pos = getPosition(L, 1);
  2849.  
  2850. Tile* tile = g_game.map.getTile(pos);
  2851. if (!tile) {
  2852. std::ostringstream ss;
  2853. ss << pos << ' ' << getErrorDesc(LUA_ERROR_TILE_NOT_FOUND);
  2854. reportErrorFunc(ss.str());
  2855. pushBoolean(L, false);
  2856. return 1;
  2857. }
  2858.  
  2859. uint32_t uid = getNumber<uint32_t>(L, 2);
  2860. Item* item = getScriptEnv()->getItemByUID(uid);
  2861. if (!item) {
  2862. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2863. pushBoolean(L, false);
  2864. return 1;
  2865. }
  2866.  
  2867. if (item->getParent() != VirtualCylinder::virtualCylinder) {
  2868. reportErrorFunc("Item already has a parent");
  2869. pushBoolean(L, false);
  2870. return 1;
  2871. }
  2872.  
  2873. lua_pushnumber(L, g_game.internalAddItem(tile, item));
  2874. return 1;
  2875. }
  2876.  
  2877. int LuaScriptInterface::luaDoCreateItem(lua_State* L)
  2878. {
  2879. //doCreateItem(itemid, <optional> type/count, pos)
  2880. //Returns uid of the created item, only works on tiles.
  2881. const Position& pos = getPosition(L, 3);
  2882. Tile* tile = g_game.map.getTile(pos);
  2883. if (!tile) {
  2884. std::ostringstream ss;
  2885. ss << pos << ' ' << getErrorDesc(LUA_ERROR_TILE_NOT_FOUND);
  2886. reportErrorFunc(ss.str());
  2887. pushBoolean(L, false);
  2888. return 1;
  2889. }
  2890.  
  2891. ScriptEnvironment* env = getScriptEnv();
  2892.  
  2893. int32_t itemCount = 1;
  2894. int32_t subType = 1;
  2895.  
  2896. uint16_t itemId = getNumber<uint16_t>(L, 1);
  2897. uint32_t count = getNumber<uint32_t>(L, 2, 1);
  2898.  
  2899. const ItemType& it = Item::items[itemId];
  2900. if (it.hasSubType()) {
  2901. if (it.stackable) {
  2902. itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
  2903. }
  2904.  
  2905. subType = count;
  2906. } else {
  2907. itemCount = std::max<int32_t>(1, count);
  2908. }
  2909.  
  2910. while (itemCount > 0) {
  2911. int32_t stackCount = std::min<int32_t>(100, subType);
  2912. Item* newItem = Item::CreateItem(itemId, stackCount);
  2913. if (!newItem) {
  2914. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2915. pushBoolean(L, false);
  2916. return 1;
  2917. }
  2918.  
  2919. if (it.stackable) {
  2920. subType -= stackCount;
  2921. }
  2922.  
  2923. ReturnValue ret = g_game.internalAddItem(tile, newItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
  2924. if (ret != RETURNVALUE_NOERROR) {
  2925. delete newItem;
  2926. pushBoolean(L, false);
  2927. return 1;
  2928. }
  2929.  
  2930. if (--itemCount == 0) {
  2931. if (newItem->getParent()) {
  2932. uint32_t uid = env->addThing(newItem);
  2933. lua_pushnumber(L, uid);
  2934. return 1;
  2935. } else {
  2936. //stackable item stacked with existing object, newItem will be released
  2937. pushBoolean(L, false);
  2938. return 1;
  2939. }
  2940. }
  2941. }
  2942.  
  2943. pushBoolean(L, false);
  2944. return 1;
  2945. }
  2946.  
  2947. int LuaScriptInterface::luaDoCreateItemEx(lua_State* L)
  2948. {
  2949. //doCreateItemEx(itemid, <optional> count/subtype)
  2950. //Returns uid of the created item
  2951. uint16_t itemId = getNumber<uint16_t>(L, 1);
  2952. uint32_t count = getNumber<uint32_t>(L, 2, 1);
  2953.  
  2954. const ItemType& it = Item::items[itemId];
  2955. if (it.stackable && count > 100) {
  2956. reportErrorFunc("Stack count cannot be higher than 100.");
  2957. count = 100;
  2958. }
  2959.  
  2960. Item* newItem = Item::CreateItem(itemId, count);
  2961. if (!newItem) {
  2962. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2963. pushBoolean(L, false);
  2964. return 1;
  2965. }
  2966.  
  2967. newItem->setParent(VirtualCylinder::virtualCylinder);
  2968.  
  2969. ScriptEnvironment* env = getScriptEnv();
  2970. env->addTempItem(newItem);
  2971.  
  2972. uint32_t uid = env->addThing(newItem);
  2973. lua_pushnumber(L, uid);
  2974. return 1;
  2975. }
  2976.  
  2977. int LuaScriptInterface::luaDebugPrint(lua_State* L)
  2978. {
  2979. //debugPrint(text)
  2980. reportErrorFunc(getString(L, -1));
  2981. return 0;
  2982. }
  2983.  
  2984. int LuaScriptInterface::luaGetWorldTime(lua_State* L)
  2985. {
  2986. //getWorldTime()
  2987. uint32_t time = g_game.getLightHour();
  2988. lua_pushnumber(L, time);
  2989. return 1;
  2990. }
  2991.  
  2992. int LuaScriptInterface::luaGetWorldLight(lua_State* L)
  2993. {
  2994. //getWorldLight()
  2995. LightInfo lightInfo;
  2996. g_game.getWorldLightInfo(lightInfo);
  2997. lua_pushnumber(L, lightInfo.level);
  2998. lua_pushnumber(L, lightInfo.color);
  2999. return 2;
  3000. }
  3001.  
  3002. int LuaScriptInterface::luaGetWorldUpTime(lua_State* L)
  3003. {
  3004. //getWorldUpTime()
  3005. uint64_t uptime = (OTSYS_TIME() - ProtocolStatus::start) / 1000;
  3006. lua_pushnumber(L, uptime);
  3007. return 1;
  3008. }
  3009.  
  3010. bool LuaScriptInterface::getArea(lua_State* L, std::list<uint32_t>& list, uint32_t& rows)
  3011. {
  3012. lua_pushnil(L);
  3013. for (rows = 0; lua_next(L, -2) != 0; ++rows) {
  3014. if (!isTable(L, -1)) {
  3015. return false;
  3016. }
  3017.  
  3018. lua_pushnil(L);
  3019. while (lua_next(L, -2) != 0) {
  3020. if (!isNumber(L, -1)) {
  3021. return false;
  3022. }
  3023. list.push_back(getNumber<uint32_t>(L, -1));
  3024. lua_pop(L, 1);
  3025. }
  3026.  
  3027. lua_pop(L, 1);
  3028. }
  3029.  
  3030. lua_pop(L, 1);
  3031. return (rows != 0);
  3032. }
  3033.  
  3034. int LuaScriptInterface::luaCreateCombatArea(lua_State* L)
  3035. {
  3036. //createCombatArea( {area}, <optional> {extArea} )
  3037. ScriptEnvironment* env = getScriptEnv();
  3038. if (env->getScriptId() != EVENT_ID_LOADING) {
  3039. reportErrorFunc("This function can only be used while loading the script.");
  3040. pushBoolean(L, false);
  3041. return 1;
  3042. }
  3043.  
  3044. uint32_t areaId = g_luaEnvironment.createAreaObject(env->getScriptInterface());
  3045. AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3046.  
  3047. int parameters = lua_gettop(L);
  3048. if (parameters >= 2) {
  3049. uint32_t rowsExtArea;
  3050. std::list<uint32_t> listExtArea;
  3051. if (!getArea(L, listExtArea, rowsExtArea)) {
  3052. reportErrorFunc("Invalid extended area table.");
  3053. pushBoolean(L, false);
  3054. return 1;
  3055. }
  3056. area->setupExtArea(listExtArea, rowsExtArea);
  3057. }
  3058.  
  3059. uint32_t rowsArea = 0;
  3060. std::list<uint32_t> listArea;
  3061. if (!getArea(L, listArea, rowsArea)) {
  3062. reportErrorFunc("Invalid area table.");
  3063. pushBoolean(L, false);
  3064. return 1;
  3065. }
  3066.  
  3067. area->setupArea(listArea, rowsArea);
  3068. lua_pushnumber(L, areaId);
  3069. return 1;
  3070. }
  3071.  
  3072. int LuaScriptInterface::luaDoAreaCombatHealth(lua_State* L)
  3073. {
  3074. //doAreaCombatHealth(cid, type, pos, area, min, max, effect[, origin = ORIGIN_SPELL])
  3075. Creature* creature = getCreature(L, 1);
  3076. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3077. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3078. pushBoolean(L, false);
  3079. return 1;
  3080. }
  3081.  
  3082. uint32_t areaId = getNumber<uint32_t>(L, 4);
  3083. const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3084. if (area || areaId == 0) {
  3085. CombatType_t combatType = getNumber<CombatType_t>(L, 2);
  3086.  
  3087. CombatParams params;
  3088. params.combatType = combatType;
  3089. params.impactEffect = getNumber<uint8_t>(L, 7);
  3090.  
  3091. CombatDamage damage;
  3092. damage.origin = getNumber<CombatOrigin>(L, 8, ORIGIN_SPELL);
  3093. damage.primary.type = combatType;
  3094. damage.primary.value = normal_random(getNumber<int32_t>(L, 6), getNumber<int32_t>(L, 5));
  3095.  
  3096. Combat::doCombatHealth(creature, getPosition(L, 3), area, damage, params);
  3097. pushBoolean(L, true);
  3098. } else {
  3099. reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3100. pushBoolean(L, false);
  3101. }
  3102. return 1;
  3103. }
  3104.  
  3105. int LuaScriptInterface::luaDoTargetCombatHealth(lua_State* L)
  3106. {
  3107. //doTargetCombatHealth(cid, target, type, min, max, effect[, origin = ORIGIN_SPELL])
  3108. Creature* creature = getCreature(L, 1);
  3109. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3110. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3111. pushBoolean(L, false);
  3112. return 1;
  3113. }
  3114.  
  3115. Creature* target = getCreature(L, 2);
  3116. if (!target) {
  3117. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3118. pushBoolean(L, false);
  3119. return 1;
  3120. }
  3121.  
  3122. CombatType_t combatType = getNumber<CombatType_t>(L, 3);
  3123.  
  3124. CombatParams params;
  3125. params.combatType = combatType;
  3126. params.impactEffect = getNumber<uint8_t>(L, 6);
  3127.  
  3128. CombatDamage damage;
  3129. damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
  3130. damage.primary.type = combatType;
  3131. damage.primary.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
  3132.  
  3133. Combat::doCombatHealth(creature, target, damage, params);
  3134. pushBoolean(L, true);
  3135. return 1;
  3136. }
  3137.  
  3138. int LuaScriptInterface::luaDoAreaCombatMana(lua_State* L)
  3139. {
  3140. //doAreaCombatMana(cid, pos, area, min, max, effect[, origin = ORIGIN_SPELL])
  3141. Creature* creature = getCreature(L, 1);
  3142. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3143. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3144. pushBoolean(L, false);
  3145. return 1;
  3146. }
  3147.  
  3148. uint32_t areaId = getNumber<uint32_t>(L, 3);
  3149. const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3150. if (area || areaId == 0) {
  3151. CombatParams params;
  3152. params.impactEffect = getNumber<uint8_t>(L, 6);
  3153.  
  3154. CombatDamage damage;
  3155. damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
  3156. damage.primary.type = COMBAT_MANADRAIN;
  3157. damage.primary.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
  3158.  
  3159. Position pos = getPosition(L, 2);
  3160. Combat::doCombatMana(creature, pos, area, damage, params);
  3161. pushBoolean(L, true);
  3162. } else {
  3163. reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3164. pushBoolean(L, false);
  3165. }
  3166. return 1;
  3167. }
  3168.  
  3169. int LuaScriptInterface::luaDoTargetCombatMana(lua_State* L)
  3170. {
  3171. //doTargetCombatMana(cid, target, min, max, effect[, origin = ORIGIN_SPELL)
  3172. Creature* creature = getCreature(L, 1);
  3173. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3174. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3175. pushBoolean(L, false);
  3176. return 1;
  3177. }
  3178.  
  3179. Creature* target = getCreature(L, 2);
  3180. if (!target) {
  3181. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3182. pushBoolean(L, false);
  3183. return 1;
  3184. }
  3185.  
  3186. CombatParams params;
  3187. params.impactEffect = getNumber<uint8_t>(L, 5);
  3188.  
  3189. CombatDamage damage;
  3190. damage.origin = getNumber<CombatOrigin>(L, 6, ORIGIN_SPELL);
  3191. damage.primary.type = COMBAT_MANADRAIN;
  3192. damage.primary.value = normal_random(getNumber<int32_t>(L, 3), getNumber<int32_t>(L, 4));
  3193.  
  3194. Combat::doCombatMana(creature, target, damage, params);
  3195. pushBoolean(L, true);
  3196. return 1;
  3197. }
  3198.  
  3199. int LuaScriptInterface::luaDoAreaCombatCondition(lua_State* L)
  3200. {
  3201. //doAreaCombatCondition(cid, pos, area, condition, effect)
  3202. Creature* creature = getCreature(L, 1);
  3203. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3204. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3205. pushBoolean(L, false);
  3206. return 1;
  3207. }
  3208.  
  3209. const Condition* condition = getUserdata<Condition>(L, 4);
  3210. if (!condition) {
  3211. reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
  3212. pushBoolean(L, false);
  3213. return 1;
  3214. }
  3215.  
  3216. uint32_t areaId = getNumber<uint32_t>(L, 3);
  3217. const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3218. if (area || areaId == 0) {
  3219. CombatParams params;
  3220. params.impactEffect = getNumber<uint8_t>(L, 5);
  3221. params.conditionList.emplace_front(condition);
  3222. Combat::doCombatCondition(creature, getPosition(L, 2), area, params);
  3223. pushBoolean(L, true);
  3224. } else {
  3225. reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3226. pushBoolean(L, false);
  3227. }
  3228. return 1;
  3229. }
  3230.  
  3231. int LuaScriptInterface::luaDoTargetCombatCondition(lua_State* L)
  3232. {
  3233. //doTargetCombatCondition(cid, target, condition, effect)
  3234. Creature* creature = getCreature(L, 1);
  3235. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3236. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3237. pushBoolean(L, false);
  3238. return 1;
  3239. }
  3240.  
  3241. Creature* target = getCreature(L, 2);
  3242. if (!target) {
  3243. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3244. pushBoolean(L, false);
  3245. return 1;
  3246. }
  3247.  
  3248. const Condition* condition = getUserdata<Condition>(L, 3);
  3249. if (!condition) {
  3250. reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
  3251. pushBoolean(L, false);
  3252. return 1;
  3253. }
  3254.  
  3255. CombatParams params;
  3256. params.impactEffect = getNumber<uint8_t>(L, 4);
  3257. params.conditionList.emplace_front(condition);
  3258. Combat::doCombatCondition(creature, target, params);
  3259. pushBoolean(L, true);
  3260. return 1;
  3261. }
  3262.  
  3263. int LuaScriptInterface::luaDoAreaCombatDispel(lua_State* L)
  3264. {
  3265. //doAreaCombatDispel(cid, pos, area, type, effect)
  3266. Creature* creature = getCreature(L, 1);
  3267. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3268. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3269. pushBoolean(L, false);
  3270. return 1;
  3271. }
  3272.  
  3273. uint32_t areaId = getNumber<uint32_t>(L, 3);
  3274. const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3275. if (area || areaId == 0) {
  3276. CombatParams params;
  3277. params.impactEffect = getNumber<uint8_t>(L, 5);
  3278. params.dispelType = getNumber<ConditionType_t>(L, 4);
  3279. Combat::doCombatDispel(creature, getPosition(L, 2), area, params);
  3280.  
  3281. pushBoolean(L, true);
  3282. } else {
  3283. reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3284. pushBoolean(L, false);
  3285. }
  3286. return 1;
  3287. }
  3288.  
  3289. int LuaScriptInterface::luaDoTargetCombatDispel(lua_State* L)
  3290. {
  3291. //doTargetCombatDispel(cid, target, type, effect)
  3292. Creature* creature = getCreature(L, 1);
  3293. if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3294. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3295. pushBoolean(L, false);
  3296. return 1;
  3297. }
  3298.  
  3299. Creature* target = getCreature(L, 2);
  3300. if (!target) {
  3301. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3302. pushBoolean(L, false);
  3303. return 1;
  3304. }
  3305.  
  3306. CombatParams params;
  3307. params.dispelType = getNumber<ConditionType_t>(L, 3);
  3308. params.impactEffect = getNumber<uint8_t>(L, 4);
  3309. Combat::doCombatDispel(creature, target, params);
  3310. pushBoolean(L, true);
  3311. return 1;
  3312. }
  3313.  
  3314. int LuaScriptInterface::luaDoChallengeCreature(lua_State* L)
  3315. {
  3316. //doChallengeCreature(cid, target)
  3317. Creature* creature = getCreature(L, 1);
  3318. if (!creature) {
  3319. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3320. pushBoolean(L, false);
  3321. return 1;
  3322. }
  3323.  
  3324. Creature* target = getCreature(L, 2);
  3325. if (!target) {
  3326. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3327. pushBoolean(L, false);
  3328. return 1;
  3329. }
  3330.  
  3331. target->challengeCreature(creature);
  3332. pushBoolean(L, true);
  3333. return 1;
  3334. }
  3335.  
  3336. int LuaScriptInterface::luaSetCreatureOutfit(lua_State* L)
  3337. {
  3338. //doSetCreatureOutfit(cid, outfit, time)
  3339. Creature* creature = getCreature(L, 1);
  3340. if (!creature) {
  3341. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3342. pushBoolean(L, false);
  3343. return 1;
  3344. }
  3345.  
  3346. Outfit_t outfit = getOutfit(L, 2);
  3347. int32_t time = getNumber<int32_t>(L, 3);
  3348. pushBoolean(L, Spell::CreateIllusion(creature, outfit, time) == RETURNVALUE_NOERROR);
  3349. return 1;
  3350. }
  3351.  
  3352. int LuaScriptInterface::luaSetMonsterOutfit(lua_State* L)
  3353. {
  3354. //doSetMonsterOutfit(cid, name, time)
  3355. Creature* creature = getCreature(L, 1);
  3356. if (!creature) {
  3357. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3358. pushBoolean(L, false);
  3359. return 1;
  3360. }
  3361.  
  3362. std::string name = getString(L, 2);
  3363. int32_t time = getNumber<int32_t>(L, 3);
  3364. pushBoolean(L, Spell::CreateIllusion(creature, name, time) == RETURNVALUE_NOERROR);
  3365. return 1;
  3366. }
  3367.  
  3368. int LuaScriptInterface::luaSetItemOutfit(lua_State* L)
  3369. {
  3370. //doSetItemOutfit(cid, item, time)
  3371. Creature* creature = getCreature(L, 1);
  3372. if (!creature) {
  3373. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3374. pushBoolean(L, false);
  3375. return 1;
  3376. }
  3377.  
  3378. uint32_t item = getNumber<uint32_t>(L, 2);
  3379. int32_t time = getNumber<int32_t>(L, 3);
  3380. pushBoolean(L, Spell::CreateIllusion(creature, item, time) == RETURNVALUE_NOERROR);
  3381. return 1;
  3382. }
  3383.  
  3384. int LuaScriptInterface::luaDoMoveCreature(lua_State* L)
  3385. {
  3386. //doMoveCreature(cid, direction)
  3387. Creature* creature = getCreature(L, 1);
  3388. if (!creature) {
  3389. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3390. pushBoolean(L, false);
  3391. return 1;
  3392. }
  3393.  
  3394. Direction direction = getNumber<Direction>(L, 2);
  3395. if (direction > DIRECTION_LAST) {
  3396. reportErrorFunc("No valid direction");
  3397. pushBoolean(L, false);
  3398. return 1;
  3399. }
  3400.  
  3401. ReturnValue ret = g_game.internalMoveCreature(creature, direction, FLAG_NOLIMIT);
  3402. lua_pushnumber(L, ret);
  3403. return 1;
  3404. }
  3405.  
  3406. int LuaScriptInterface::luaIsValidUID(lua_State* L)
  3407. {
  3408. //isValidUID(uid)
  3409. pushBoolean(L, getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, -1)) != nullptr);
  3410. return 1;
  3411. }
  3412.  
  3413. int LuaScriptInterface::luaIsDepot(lua_State* L)
  3414. {
  3415. //isDepot(uid)
  3416. Container* container = getScriptEnv()->getContainerByUID(getNumber<uint32_t>(L, -1));
  3417. pushBoolean(L, container && container->getDepotLocker());
  3418. return 1;
  3419. }
  3420.  
  3421. int LuaScriptInterface::luaIsMoveable(lua_State* L)
  3422. {
  3423. //isMoveable(uid)
  3424. //isMovable(uid)
  3425. Thing* thing = getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, -1));
  3426. pushBoolean(L, thing && thing->isPushable());
  3427. return 1;
  3428. }
  3429.  
  3430. int LuaScriptInterface::luaDoAddContainerItem(lua_State* L)
  3431. {
  3432. //doAddContainerItem(uid, itemid, <optional> count/subtype)
  3433. uint32_t uid = getNumber<uint32_t>(L, 1);
  3434.  
  3435. ScriptEnvironment* env = getScriptEnv();
  3436. Container* container = env->getContainerByUID(uid);
  3437. if (!container) {
  3438. reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
  3439. pushBoolean(L, false);
  3440. return 1;
  3441. }
  3442.  
  3443. uint16_t itemId = getNumber<uint16_t>(L, 2);
  3444. const ItemType& it = Item::items[itemId];
  3445.  
  3446. int32_t itemCount = 1;
  3447. int32_t subType = 1;
  3448. uint32_t count = getNumber<uint32_t>(L, 3, 1);
  3449.  
  3450. if (it.hasSubType()) {
  3451. if (it.stackable) {
  3452. itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
  3453. }
  3454.  
  3455. subType = count;
  3456. } else {
  3457. itemCount = std::max<int32_t>(1, count);
  3458. }
  3459.  
  3460. while (itemCount > 0) {
  3461. int32_t stackCount = std::min<int32_t>(100, subType);
  3462. Item* newItem = Item::CreateItem(itemId, stackCount);
  3463. if (!newItem) {
  3464. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  3465. pushBoolean(L, false);
  3466. return 1;
  3467. }
  3468.  
  3469. if (it.stackable) {
  3470. subType -= stackCount;
  3471. }
  3472.  
  3473. ReturnValue ret = g_game.internalAddItem(container, newItem);
  3474. if (ret != RETURNVALUE_NOERROR) {
  3475. delete newItem;
  3476. pushBoolean(L, false);
  3477. return 1;
  3478. }
  3479.  
  3480. if (--itemCount == 0) {
  3481. if (newItem->getParent()) {
  3482. lua_pushnumber(L, env->addThing(newItem));
  3483. } else {
  3484. //stackable item stacked with existing object, newItem will be released
  3485. pushBoolean(L, false);
  3486. }
  3487. return 1;
  3488. }
  3489. }
  3490.  
  3491. pushBoolean(L, false);
  3492. return 1;
  3493. }
  3494.  
  3495. int LuaScriptInterface::luaGetDepotId(lua_State* L)
  3496. {
  3497. //getDepotId(uid)
  3498. uint32_t uid = getNumber<uint32_t>(L, -1);
  3499.  
  3500. Container* container = getScriptEnv()->getContainerByUID(uid);
  3501. if (!container) {
  3502. reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
  3503. pushBoolean(L, false);
  3504. return 1;
  3505. }
  3506.  
  3507. DepotLocker* depotLocker = container->getDepotLocker();
  3508. if (!depotLocker) {
  3509. reportErrorFunc("Depot not found");
  3510. pushBoolean(L, false);
  3511. return 1;
  3512. }
  3513.  
  3514. lua_pushnumber(L, depotLocker->getDepotId());
  3515. return 1;
  3516. }
  3517.  
  3518. int LuaScriptInterface::luaIsInArray(lua_State* L)
  3519. {
  3520. //isInArray(array, value)
  3521. if (!isTable(L, 1)) {
  3522. pushBoolean(L, false);
  3523. return 1;
  3524. }
  3525.  
  3526. lua_pushnil(L);
  3527. while (lua_next(L, 1)) {
  3528. if (lua_equal(L, 2, -1) != 0) {
  3529. pushBoolean(L, true);
  3530. return 1;
  3531. }
  3532. lua_pop(L, 1);
  3533. }
  3534.  
  3535. pushBoolean(L, false);
  3536. return 1;
  3537. }
  3538.  
  3539. int LuaScriptInterface::luaDoSetCreatureLight(lua_State* L)
  3540. {
  3541. //doSetCreatureLight(cid, lightLevel, lightColor, time)
  3542. Creature* creature = getCreature(L, 1);
  3543. if (!creature) {
  3544. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  3545. pushBoolean(L, false);
  3546. return 1;
  3547. }
  3548.  
  3549. uint16_t level = getNumber<uint16_t>(L, 2);
  3550. uint16_t color = getNumber<uint16_t>(L, 3);
  3551. uint32_t time = getNumber<uint32_t>(L, 4);
  3552. Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_LIGHT, time, level | (color << 8));
  3553. creature->addCondition(condition);
  3554. pushBoolean(L, true);
  3555. return 1;
  3556. }
  3557.  
  3558. int LuaScriptInterface::luaAddEvent(lua_State* L)
  3559. {
  3560. //addEvent(callback, delay, ...)
  3561. lua_State* globalState = g_luaEnvironment.getLuaState();
  3562. if (!globalState) {
  3563. reportErrorFunc("No valid script interface!");
  3564. pushBoolean(L, false);
  3565. return 1;
  3566. } else if (globalState != L) {
  3567. lua_xmove(L, globalState, lua_gettop(L));
  3568. }
  3569.  
  3570. int parameters = lua_gettop(globalState);
  3571. if (!isFunction(globalState, -parameters)) { //-parameters means the first parameter from left to right
  3572. reportErrorFunc("callback parameter should be a function.");
  3573. pushBoolean(L, false);
  3574. return 1;
  3575. }
  3576.  
  3577. if (g_config.getBoolean(ConfigManager::WARN_UNSAFE_SCRIPTS) || g_config.getBoolean(ConfigManager::CONVERT_UNSAFE_SCRIPTS)) {
  3578. std::vector<std::pair<int32_t, LuaDataType>> indexes;
  3579. for (int i = 3; i <= parameters; ++i) {
  3580. if (lua_getmetatable(globalState, i) == 0) {
  3581. continue;
  3582. }
  3583. lua_rawgeti(L, -1, 't');
  3584.  
  3585. LuaDataType type = getNumber<LuaDataType>(L, -1);
  3586. if (type != LuaData_Unknown && type != LuaData_Tile) {
  3587. indexes.push_back({i, type});
  3588. }
  3589. lua_pop(globalState, 2);
  3590. }
  3591.  
  3592. if (!indexes.empty()) {
  3593. if (g_config.getBoolean(ConfigManager::WARN_UNSAFE_SCRIPTS)) {
  3594. bool plural = indexes.size() > 1;
  3595.  
  3596. std::string warningString = "Argument";
  3597. if (plural) {
  3598. warningString += 's';
  3599. }
  3600.  
  3601. for (const auto& entry : indexes) {
  3602. if (entry == indexes.front()) {
  3603. warningString += ' ';
  3604. } else if (entry == indexes.back()) {
  3605. warningString += " and ";
  3606. } else {
  3607. warningString += ", ";
  3608. }
  3609. warningString += '#';
  3610. warningString += std::to_string(entry.first);
  3611. }
  3612.  
  3613. if (plural) {
  3614. warningString += " are unsafe";
  3615. } else {
  3616. warningString += " is unsafe";
  3617. }
  3618.  
  3619. reportErrorFunc(warningString);
  3620. }
  3621.  
  3622. if (g_config.getBoolean(ConfigManager::CONVERT_UNSAFE_SCRIPTS)) {
  3623. for (const auto& entry : indexes) {
  3624. switch (entry.second) {
  3625. case LuaData_Item:
  3626. case LuaData_Container:
  3627. case LuaData_Teleport: {
  3628. lua_getglobal(globalState, "Item");
  3629. lua_getfield(globalState, -1, "getUniqueId");
  3630. break;
  3631. }
  3632. case LuaData_Player:
  3633. case LuaData_Monster:
  3634. case LuaData_Npc: {
  3635. lua_getglobal(globalState, "Creature");
  3636. lua_getfield(globalState, -1, "getId");
  3637. break;
  3638. }
  3639. default:
  3640. break;
  3641. }
  3642. lua_replace(globalState, -2);
  3643. lua_pushvalue(globalState, entry.first);
  3644. lua_call(globalState, 1, 1);
  3645. lua_replace(globalState, entry.first);
  3646. }
  3647. }
  3648. }
  3649. }
  3650.  
  3651. LuaTimerEventDesc eventDesc;
  3652. for (int i = 0; i < parameters - 2; ++i) { //-2 because addEvent needs at least two parameters
  3653. eventDesc.parameters.push_back(luaL_ref(globalState, LUA_REGISTRYINDEX));
  3654. }
  3655.  
  3656. uint32_t delay = std::max<uint32_t>(100, getNumber<uint32_t>(globalState, 2));
  3657. lua_pop(globalState, 1);
  3658.  
  3659. eventDesc.function = luaL_ref(globalState, LUA_REGISTRYINDEX);
  3660. eventDesc.scriptId = getScriptEnv()->getScriptId();
  3661.  
  3662. auto& lastTimerEventId = g_luaEnvironment.m_lastEventTimerId;
  3663. eventDesc.eventId = g_scheduler.addEvent(createSchedulerTask(
  3664. delay, std::bind(&LuaEnvironment::executeTimerEvent, &g_luaEnvironment, lastTimerEventId)
  3665. ));
  3666.  
  3667. g_luaEnvironment.m_timerEvents.emplace(lastTimerEventId, std::move(eventDesc));
  3668. lua_pushnumber(L, lastTimerEventId++);
  3669. return 1;
  3670. }
  3671.  
  3672. int LuaScriptInterface::luaStopEvent(lua_State* L)
  3673. {
  3674. //stopEvent(eventid)
  3675. lua_State* globalState = g_luaEnvironment.getLuaState();
  3676. if (!globalState) {
  3677. reportErrorFunc("No valid script interface!");
  3678. pushBoolean(L, false);
  3679. return 1;
  3680. }
  3681.  
  3682. uint32_t eventId = getNumber<uint32_t>(L, 1);
  3683.  
  3684. auto& timerEvents = g_luaEnvironment.m_timerEvents;
  3685. auto it = timerEvents.find(eventId);
  3686. if (it == timerEvents.end()) {
  3687. pushBoolean(L, false);
  3688. return 1;
  3689. }
  3690.  
  3691. LuaTimerEventDesc timerEventDesc = std::move(it->second);
  3692. timerEvents.erase(it);
  3693.  
  3694. g_scheduler.stopEvent(timerEventDesc.eventId);
  3695. luaL_unref(globalState, LUA_REGISTRYINDEX, timerEventDesc.function);
  3696.  
  3697. for (auto parameter : timerEventDesc.parameters) {
  3698. luaL_unref(globalState, LUA_REGISTRYINDEX, parameter);
  3699. }
  3700.  
  3701. pushBoolean(L, true);
  3702. return 1;
  3703. }
  3704.  
  3705. int LuaScriptInterface::luaGetCreatureCondition(lua_State* L)
  3706. {
  3707. Creature* creature = getCreature(L, 1);
  3708. if (!creature) {
  3709. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3710. pushBoolean(L, false);
  3711. return 1;
  3712. }
  3713.  
  3714. ConditionType_t condition = getNumber<ConditionType_t>(L, 2);
  3715. uint32_t subId = getNumber<uint32_t>(L, 3, 0);
  3716. pushBoolean(L, creature->hasCondition(condition, subId));
  3717. return 1;
  3718. }
  3719.  
  3720. int LuaScriptInterface::luaSaveServer(lua_State* L)
  3721. {
  3722. g_game.saveGameState();
  3723. pushBoolean(L, true);
  3724. return 1;
  3725. }
  3726.  
  3727. int LuaScriptInterface::luaCleanMap(lua_State* L)
  3728. {
  3729. lua_pushnumber(L, g_game.map.clean());
  3730. return 1;
  3731. }
  3732.  
  3733. int LuaScriptInterface::luaIsInWar(lua_State* L)
  3734. {
  3735. //isInWar(cid, target)
  3736. Player* player = getPlayer(L, 1);
  3737. if (!player) {
  3738. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  3739. pushBoolean(L, false);
  3740. return 1;
  3741. }
  3742.  
  3743. Player* targetPlayer = getPlayer(L, 2);
  3744. if (!targetPlayer) {
  3745. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  3746. pushBoolean(L, false);
  3747. return 1;
  3748. }
  3749.  
  3750. pushBoolean(L, player->isInWar(targetPlayer));
  3751. return 1;
  3752. }
  3753.  
  3754. int LuaScriptInterface::luaGetWaypointPositionByName(lua_State* L)
  3755. {
  3756. //getWaypointPositionByName(name)
  3757. auto& waypoints = g_game.map.waypoints;
  3758.  
  3759. auto it = waypoints.find(getString(L, -1));
  3760. if (it != waypoints.end()) {
  3761. pushPosition(L, it->second);
  3762. } else {
  3763. pushBoolean(L, false);
  3764. }
  3765. return 1;
  3766. }
  3767.  
  3768. int LuaScriptInterface::luaSendChannelMessage(lua_State* L)
  3769. {
  3770. //sendChannelMessage(channelId, type, message)
  3771. uint32_t channelId = getNumber<uint32_t>(L, 1);
  3772. ChatChannel* channel = g_chat->getChannelById(channelId);
  3773. if (!channel) {
  3774. pushBoolean(L, false);
  3775. return 1;
  3776. }
  3777.  
  3778. SpeakClasses type = getNumber<SpeakClasses>(L, 2);
  3779. std::string message = getString(L, 3);
  3780. channel->sendToAll(message, type);
  3781. pushBoolean(L, true);
  3782. return 1;
  3783. }
  3784.  
  3785. int LuaScriptInterface::luaSendGuildChannelMessage(lua_State* L)
  3786. {
  3787. //sendGuildChannelMessage(guildId, type, message)
  3788. uint32_t guildId = getNumber<uint32_t>(L, 1);
  3789. ChatChannel* channel = g_chat->getGuildChannelById(guildId);
  3790. if (!channel) {
  3791. pushBoolean(L, false);
  3792. return 1;
  3793. }
  3794.  
  3795. SpeakClasses type = getNumber<SpeakClasses>(L, 2);
  3796. std::string message = getString(L, 3);
  3797. channel->sendToAll(message, type);
  3798. pushBoolean(L, true);
  3799. return 1;
  3800. }
  3801.  
  3802. std::string LuaScriptInterface::escapeString(const std::string& string)
  3803. {
  3804. std::string s = string;
  3805. replaceString(s, "\\", "\\\\");
  3806. replaceString(s, "\"", "\\\"");
  3807. replaceString(s, "'", "\\'");
  3808. replaceString(s, "[[", "\\[[");
  3809. return s;
  3810. }
  3811.  
  3812. #ifndef LUAJIT_VERSION
  3813. const luaL_Reg LuaScriptInterface::luaBitReg[] = {
  3814. //{"tobit", LuaScriptInterface::luaBitToBit},
  3815. {"bnot", LuaScriptInterface::luaBitNot},
  3816. {"band", LuaScriptInterface::luaBitAnd},
  3817. {"bor", LuaScriptInterface::luaBitOr},
  3818. {"bxor", LuaScriptInterface::luaBitXor},
  3819. {"lshift", LuaScriptInterface::luaBitLeftShift},
  3820. {"rshift", LuaScriptInterface::luaBitRightShift},
  3821. //{"arshift", LuaScriptInterface::luaBitArithmeticalRightShift},
  3822. //{"rol", LuaScriptInterface::luaBitRotateLeft},
  3823. //{"ror", LuaScriptInterface::luaBitRotateRight},
  3824. //{"bswap", LuaScriptInterface::luaBitSwapEndian},
  3825. //{"tohex", LuaScriptInterface::luaBitToHex},
  3826. {nullptr, nullptr}
  3827. };
  3828.  
  3829. int LuaScriptInterface::luaBitNot(lua_State* L)
  3830. {
  3831. lua_pushnumber(L, ~getNumber<uint32_t>(L, -1));
  3832. return 1;
  3833. }
  3834.  
  3835. #define MULTIOP(name, op) \
  3836. int LuaScriptInterface::luaBit##name(lua_State* L) \
  3837. { \
  3838. int n = lua_gettop(L); \
  3839. uint32_t w = getNumber<uint32_t>(L, -1); \
  3840. for (int i = 1; i < n; ++i) \
  3841. w op getNumber<uint32_t>(L, i); \
  3842. lua_pushnumber(L, w); \
  3843. return 1; \
  3844. }
  3845.  
  3846. MULTIOP(And, &= )
  3847. MULTIOP(Or, |= )
  3848. MULTIOP(Xor, ^= )
  3849.  
  3850. #define SHIFTOP(name, op) \
  3851. int LuaScriptInterface::luaBit##name(lua_State* L) \
  3852. { \
  3853. uint32_t n1 = getNumber<uint32_t>(L, 1), n2 = getNumber<uint32_t>(L, 2); \
  3854. lua_pushnumber(L, (n1 op n2)); \
  3855. return 1; \
  3856. }
  3857.  
  3858. SHIFTOP(LeftShift, << )
  3859. SHIFTOP(RightShift, >> )
  3860. #endif
  3861.  
  3862. const luaL_Reg LuaScriptInterface::luaConfigManagerTable[] = {
  3863. {"getString", LuaScriptInterface::luaConfigManagerGetString},
  3864. {"getNumber", LuaScriptInterface::luaConfigManagerGetNumber},
  3865. {"getBoolean", LuaScriptInterface::luaConfigManagerGetBoolean},
  3866. {nullptr, nullptr}
  3867. };
  3868.  
  3869. int LuaScriptInterface::luaConfigManagerGetString(lua_State* L)
  3870. {
  3871. pushString(L, g_config.getString(getNumber<ConfigManager::string_config_t>(L, -1)));
  3872. return 1;
  3873. }
  3874.  
  3875. int LuaScriptInterface::luaConfigManagerGetNumber(lua_State* L)
  3876. {
  3877. lua_pushnumber(L, g_config.getNumber(getNumber<ConfigManager::integer_config_t>(L, -1)));
  3878. return 1;
  3879. }
  3880.  
  3881. int LuaScriptInterface::luaConfigManagerGetBoolean(lua_State* L)
  3882. {
  3883. pushBoolean(L, g_config.getBoolean(getNumber<ConfigManager::boolean_config_t>(L, -1)));
  3884. return 1;
  3885. }
  3886.  
  3887. const luaL_Reg LuaScriptInterface::luaDatabaseTable[] = {
  3888. {"query", LuaScriptInterface::luaDatabaseExecute},
  3889. {"asyncQuery", LuaScriptInterface::luaDatabaseAsyncExecute},
  3890. {"storeQuery", LuaScriptInterface::luaDatabaseStoreQuery},
  3891. {"asyncStoreQuery", LuaScriptInterface::luaDatabaseAsyncStoreQuery},
  3892. {"escapeString", LuaScriptInterface::luaDatabaseEscapeString},
  3893. {"escapeBlob", LuaScriptInterface::luaDatabaseEscapeBlob},
  3894. {"lastInsertId", LuaScriptInterface::luaDatabaseLastInsertId},
  3895. {"tableExists", LuaScriptInterface::luaDatabaseTableExists},
  3896. {nullptr, nullptr}
  3897. };
  3898.  
  3899. int LuaScriptInterface::luaDatabaseExecute(lua_State* L)
  3900. {
  3901. pushBoolean(L, Database::getInstance()->executeQuery(getString(L, -1)));
  3902. return 1;
  3903. }
  3904.  
  3905. int LuaScriptInterface::luaDatabaseAsyncExecute(lua_State* L)
  3906. {
  3907. std::function<void(DBResult_ptr, bool)> callback;
  3908. if (lua_gettop(L) > 1) {
  3909. int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
  3910. auto scriptId = getScriptEnv()->getScriptId();
  3911. callback = [ref, scriptId](DBResult_ptr, bool success) {
  3912. lua_State* luaState = g_luaEnvironment.getLuaState();
  3913. if (!luaState) {
  3914. return;
  3915. }
  3916.  
  3917. if (!LuaScriptInterface::reserveScriptEnv()) {
  3918. luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3919. return;
  3920. }
  3921.  
  3922. lua_rawgeti(luaState, LUA_REGISTRYINDEX, ref);
  3923. pushBoolean(luaState, success);
  3924. auto env = getScriptEnv();
  3925. env->setScriptId(scriptId, &g_luaEnvironment);
  3926. g_luaEnvironment.callFunction(1);
  3927.  
  3928. luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3929. };
  3930. }
  3931. g_databaseTasks.addTask(getString(L, -1), callback);
  3932. return 0;
  3933. }
  3934.  
  3935. int LuaScriptInterface::luaDatabaseStoreQuery(lua_State* L)
  3936. {
  3937. if (DBResult_ptr res = Database::getInstance()->storeQuery(getString(L, -1))) {
  3938. lua_pushnumber(L, ScriptEnvironment::addResult(res));
  3939. } else {
  3940. pushBoolean(L, false);
  3941. }
  3942. return 1;
  3943. }
  3944.  
  3945. int LuaScriptInterface::luaDatabaseAsyncStoreQuery(lua_State* L)
  3946. {
  3947. std::function<void(DBResult_ptr, bool)> callback;
  3948. if (lua_gettop(L) > 1) {
  3949. int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
  3950. auto scriptId = getScriptEnv()->getScriptId();
  3951. callback = [ref, scriptId](DBResult_ptr result, bool) {
  3952. lua_State* luaState = g_luaEnvironment.getLuaState();
  3953. if (!luaState) {
  3954. return;
  3955. }
  3956.  
  3957. if (!LuaScriptInterface::reserveScriptEnv()) {
  3958. luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3959. return;
  3960. }
  3961.  
  3962. lua_rawgeti(luaState, LUA_REGISTRYINDEX, ref);
  3963. if (result) {
  3964. lua_pushnumber(luaState, ScriptEnvironment::addResult(result));
  3965. } else {
  3966. pushBoolean(luaState, false);
  3967. }
  3968. auto env = getScriptEnv();
  3969. env->setScriptId(scriptId, &g_luaEnvironment);
  3970. g_luaEnvironment.callFunction(1);
  3971.  
  3972. luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3973. };
  3974. }
  3975. g_databaseTasks.addTask(getString(L, -1), callback, true);
  3976. return 0;
  3977. }
  3978.  
  3979. int LuaScriptInterface::luaDatabaseEscapeString(lua_State* L)
  3980. {
  3981. pushString(L, Database::getInstance()->escapeString(getString(L, -1)));
  3982. return 1;
  3983. }
  3984.  
  3985. int LuaScriptInterface::luaDatabaseEscapeBlob(lua_State* L)
  3986. {
  3987. uint32_t length = getNumber<uint32_t>(L, 2);
  3988. pushString(L, Database::getInstance()->escapeBlob(getString(L, 1).c_str(), length));
  3989. return 1;
  3990. }
  3991.  
  3992. int LuaScriptInterface::luaDatabaseLastInsertId(lua_State* L)
  3993. {
  3994. lua_pushnumber(L, Database::getInstance()->getLastInsertId());
  3995. return 1;
  3996. }
  3997.  
  3998. int LuaScriptInterface::luaDatabaseTableExists(lua_State* L)
  3999. {
  4000. pushBoolean(L, DatabaseManager::tableExists(getString(L, -1)));
  4001. return 1;
  4002. }
  4003.  
  4004. const luaL_Reg LuaScriptInterface::luaResultTable[] = {
  4005. {"getNumber", LuaScriptInterface::luaResultGetNumber},
  4006. {"getString", LuaScriptInterface::luaResultGetString},
  4007. {"getStream", LuaScriptInterface::luaResultGetStream},
  4008. {"next", LuaScriptInterface::luaResultNext},
  4009. {"free", LuaScriptInterface::luaResultFree},
  4010. {nullptr, nullptr}
  4011. };
  4012.  
  4013. int LuaScriptInterface::luaResultGetNumber(lua_State* L)
  4014. {
  4015. DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
  4016. if (!res) {
  4017. pushBoolean(L, false);
  4018. return 1;
  4019. }
  4020.  
  4021. const std::string& s = getString(L, 2);
  4022. lua_pushnumber(L, res->getNumber<int64_t>(s));
  4023. return 1;
  4024. }
  4025.  
  4026. int LuaScriptInterface::luaResultGetString(lua_State* L)
  4027. {
  4028. DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
  4029. if (!res) {
  4030. pushBoolean(L, false);
  4031. return 1;
  4032. }
  4033.  
  4034. const std::string& s = getString(L, 2);
  4035. pushString(L, res->getString(s));
  4036. return 1;
  4037. }
  4038.  
  4039. int LuaScriptInterface::luaResultGetStream(lua_State* L)
  4040. {
  4041. DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
  4042. if (!res) {
  4043. pushBoolean(L, false);
  4044. return 1;
  4045. }
  4046.  
  4047. unsigned long length;
  4048. const char* stream = res->getStream(getString(L, 2), length);
  4049. lua_pushlstring(L, stream, length);
  4050. lua_pushnumber(L, length);
  4051. return 2;
  4052. }
  4053.  
  4054. int LuaScriptInterface::luaResultNext(lua_State* L)
  4055. {
  4056. DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, -1));
  4057. if (!res) {
  4058. pushBoolean(L, false);
  4059. return 1;
  4060. }
  4061.  
  4062. pushBoolean(L, res->next());
  4063. return 1;
  4064. }
  4065.  
  4066. int LuaScriptInterface::luaResultFree(lua_State* L)
  4067. {
  4068. pushBoolean(L, ScriptEnvironment::removeResult(getNumber<uint32_t>(L, -1)));
  4069. return 1;
  4070. }
  4071.  
  4072. // Userdata
  4073. int LuaScriptInterface::luaUserdataCompare(lua_State* L)
  4074. {
  4075. // userdataA == userdataB
  4076. pushBoolean(L, getUserdata<void>(L, 1) == getUserdata<void>(L, 2));
  4077. return 1;
  4078. }
  4079.  
  4080. // _G
  4081. int LuaScriptInterface::luaIsType(lua_State* L)
  4082. {
  4083. // isType(derived, base)
  4084. lua_getmetatable(L, -2);
  4085. lua_getmetatable(L, -2);
  4086.  
  4087. lua_rawgeti(L, -2, 'p');
  4088. uint_fast8_t parentsB = getNumber<uint_fast8_t>(L, 1);
  4089.  
  4090. lua_rawgeti(L, -3, 'h');
  4091. size_t hashB = getNumber<size_t>(L, 1);
  4092.  
  4093. lua_rawgeti(L, -3, 'p');
  4094. uint_fast8_t parentsA = getNumber<uint_fast8_t>(L, 1);
  4095. for (uint_fast8_t i = parentsA; i < parentsB; ++i) {
  4096. lua_getfield(L, -3, "__index");
  4097. lua_replace(L, -4);
  4098. }
  4099.  
  4100. lua_rawgeti(L, -4, 'h');
  4101. size_t hashA = getNumber<size_t>(L, 1);
  4102.  
  4103. pushBoolean(L, hashA == hashB);
  4104. return 1;
  4105. }
  4106.  
  4107. int LuaScriptInterface::luaRawGetMetatable(lua_State* L)
  4108. {
  4109. // rawgetmetatable(metatableName)
  4110. luaL_getmetatable(L, getString(L, 1).c_str());
  4111. return 1;
  4112. }
  4113.  
  4114. // os
  4115. int LuaScriptInterface::luaSystemTime(lua_State* L)
  4116. {
  4117. // os.mtime()
  4118. lua_pushnumber(L, OTSYS_TIME());
  4119. return 1;
  4120. }
  4121.  
  4122. // table
  4123. int LuaScriptInterface::luaTableCreate(lua_State* L)
  4124. {
  4125. // table.create(arrayLength, keyLength)
  4126. lua_createtable(L, getNumber<int32_t>(L, 1), getNumber<int32_t>(L, 2));
  4127. return 1;
  4128. }
  4129.  
  4130. // Game
  4131. int LuaScriptInterface::luaGameGetSpectators(lua_State* L)
  4132. {
  4133. // Game.getSpectators(position[, multifloor = false[, onlyPlayer = false[, minRangeX = 0[, maxRangeX = 0[, minRangeY = 0[, maxRangeY = 0]]]]]])
  4134. const Position& position = getPosition(L, 1);
  4135. bool multifloor = getBoolean(L, 2, false);
  4136. bool onlyPlayers = getBoolean(L, 3, false);
  4137. int32_t minRangeX = getNumber<int32_t>(L, 4, 0);
  4138. int32_t maxRangeX = getNumber<int32_t>(L, 5, 0);
  4139. int32_t minRangeY = getNumber<int32_t>(L, 6, 0);
  4140. int32_t maxRangeY = getNumber<int32_t>(L, 7, 0);
  4141.  
  4142. SpectatorVec spectators;
  4143. g_game.map.getSpectators(spectators, position, multifloor, onlyPlayers, minRangeX, maxRangeX, minRangeY, maxRangeY);
  4144.  
  4145. lua_createtable(L, spectators.size(), 0);
  4146.  
  4147. int index = 0;
  4148. for (Creature* creature : spectators) {
  4149. pushUserdata<Creature>(L, creature);
  4150. setCreatureMetatable(L, -1, creature);
  4151. lua_rawseti(L, -2, ++index);
  4152. }
  4153. return 1;
  4154. }
  4155.  
  4156. int LuaScriptInterface::luaGameGetPlayers(lua_State* L)
  4157. {
  4158. // Game.getPlayers()
  4159. lua_createtable(L, g_game.getPlayersOnline(), 0);
  4160.  
  4161. int index = 0;
  4162. for (const auto& playerEntry : g_game.getPlayers()) {
  4163. pushUserdata<Player>(L, playerEntry.second);
  4164. setMetatable(L, -1, "Player");
  4165. lua_rawseti(L, -2, ++index);
  4166. }
  4167. return 1;
  4168. }
  4169.  
  4170. int LuaScriptInterface::luaGameLoadMap(lua_State* L)
  4171. {
  4172. // Game.loadMap(path)
  4173. const std::string& path = getString(L, 1);
  4174. g_dispatcher.addTask(createTask(std::bind(&Game::loadMap, &g_game, path)));
  4175. return 0;
  4176. }
  4177.  
  4178. int LuaScriptInterface::luaGameGetExperienceStage(lua_State* L)
  4179. {
  4180. // Game.getExperienceStage(level)
  4181. uint32_t level = getNumber<uint32_t>(L, 1);
  4182. lua_pushnumber(L, g_game.getExperienceStage(level));
  4183. return 1;
  4184. }
  4185.  
  4186. int LuaScriptInterface::luaGameGetMonsterCount(lua_State* L)
  4187. {
  4188. // Game.getMonsterCount()
  4189. lua_pushnumber(L, g_game.getMonstersOnline());
  4190. return 1;
  4191. }
  4192.  
  4193. int LuaScriptInterface::luaGameGetPlayerCount(lua_State* L)
  4194. {
  4195. // Game.getPlayerCount()
  4196. lua_pushnumber(L, g_game.getPlayersOnline());
  4197. return 1;
  4198. }
  4199.  
  4200. int LuaScriptInterface::luaGameGetNpcCount(lua_State* L)
  4201. {
  4202. // Game.getNpcCount()
  4203. lua_pushnumber(L, g_game.getNpcsOnline());
  4204. return 1;
  4205. }
  4206.  
  4207. int LuaScriptInterface::luaGameGetTowns(lua_State* L)
  4208. {
  4209. // Game.getTowns()
  4210. const auto& towns = g_game.map.towns.getTowns();
  4211. lua_createtable(L, towns.size(), 0);
  4212.  
  4213. int index = 0;
  4214. for (auto townEntry : towns) {
  4215. pushUserdata<Town>(L, townEntry.second);
  4216. setMetatable(L, -1, "Town");
  4217. lua_rawseti(L, -2, ++index);
  4218. }
  4219. return 1;
  4220. }
  4221.  
  4222. int LuaScriptInterface::luaGameGetHouses(lua_State* L)
  4223. {
  4224. // Game.getHouses()
  4225. const auto& houses = g_game.map.houses.getHouses();
  4226. lua_createtable(L, houses.size(), 0);
  4227.  
  4228. int index = 0;
  4229. for (auto houseEntry : houses) {
  4230. pushUserdata<House>(L, houseEntry.second);
  4231. setMetatable(L, -1, "House");
  4232. lua_rawseti(L, -2, ++index);
  4233. }
  4234. return 1;
  4235. }
  4236.  
  4237. int LuaScriptInterface::luaGameGetGameState(lua_State* L)
  4238. {
  4239. // Game.getGameState()
  4240. lua_pushnumber(L, g_game.getGameState());
  4241. return 1;
  4242. }
  4243.  
  4244. int LuaScriptInterface::luaGameSetGameState(lua_State* L)
  4245. {
  4246. // Game.setGameState(state)
  4247. GameState_t state = getNumber<GameState_t>(L, 1);
  4248. g_game.setGameState(state);
  4249. pushBoolean(L, true);
  4250. return 1;
  4251. }
  4252.  
  4253. int LuaScriptInterface::luaGameGetWorldType(lua_State* L)
  4254. {
  4255. // Game.getWorldType()
  4256. lua_pushnumber(L, g_game.getWorldType());
  4257. return 1;
  4258. }
  4259.  
  4260. int LuaScriptInterface::luaGameSetWorldType(lua_State* L)
  4261. {
  4262. // Game.setWorldType(type)
  4263. WorldType_t type = getNumber<WorldType_t>(L, 1);
  4264. g_game.setWorldType(type);
  4265. pushBoolean(L, true);
  4266. return 1;
  4267. }
  4268.  
  4269. int LuaScriptInterface::luaGameGetReturnMessage(lua_State* L)
  4270. {
  4271. // Game.getReturnMessage(value)
  4272. ReturnValue value = getNumber<ReturnValue>(L, 1);
  4273. pushString(L, getReturnMessage(value));
  4274. return 1;
  4275. }
  4276.  
  4277. int LuaScriptInterface::luaGameCreateItem(lua_State* L)
  4278. {
  4279. // Game.createItem(itemId[, count[, position]])
  4280. uint16_t count = getNumber<uint16_t>(L, 2, 1);
  4281. uint16_t id;
  4282. if (isNumber(L, 1)) {
  4283. id = getNumber<uint16_t>(L, 1);
  4284. } else {
  4285. id = Item::items.getItemIdByName(getString(L, 1));
  4286. if (id == 0) {
  4287. lua_pushnil(L);
  4288. return 1;
  4289. }
  4290. }
  4291.  
  4292. const ItemType& it = Item::items[id];
  4293. if (it.stackable) {
  4294. count = std::min<uint16_t>(count, 100);
  4295. }
  4296.  
  4297. Item* item = Item::CreateItem(id, count);
  4298. if (!item) {
  4299. lua_pushnil(L);
  4300. return 1;
  4301. }
  4302.  
  4303. if (lua_gettop(L) >= 3) {
  4304. const Position& position = getPosition(L, 3);
  4305. Tile* tile = g_game.map.getTile(position);
  4306. if (!tile) {
  4307. delete item;
  4308. lua_pushnil(L);
  4309. return 1;
  4310. }
  4311.  
  4312. g_game.internalAddItem(tile, item, INDEX_WHEREEVER, FLAG_NOLIMIT);
  4313. } else {
  4314. getScriptEnv()->addTempItem(item);
  4315. item->setParent(VirtualCylinder::virtualCylinder);
  4316. }
  4317.  
  4318. pushUserdata<Item>(L, item);
  4319. setItemMetatable(L, -1, item);
  4320. return 1;
  4321. }
  4322.  
  4323. int LuaScriptInterface::luaGameCreateContainer(lua_State* L)
  4324. {
  4325. // Game.createContainer(itemId, size[, position])
  4326. uint16_t size = getNumber<uint16_t>(L, 2);
  4327. uint16_t id;
  4328. if (isNumber(L, 1)) {
  4329. id = getNumber<uint16_t>(L, 1);
  4330. } else {
  4331. id = Item::items.getItemIdByName(getString(L, 1));
  4332. if (id == 0) {
  4333. lua_pushnil(L);
  4334. return 1;
  4335. }
  4336. }
  4337.  
  4338. Container* container = Item::CreateItemAsContainer(id, size);
  4339. if (!container) {
  4340. lua_pushnil(L);
  4341. return 1;
  4342. }
  4343.  
  4344. if (lua_gettop(L) >= 3) {
  4345. const Position& position = getPosition(L, 3);
  4346. Tile* tile = g_game.map.getTile(position);
  4347. if (!tile) {
  4348. delete container;
  4349. lua_pushnil(L);
  4350. return 1;
  4351. }
  4352.  
  4353. g_game.internalAddItem(tile, container, INDEX_WHEREEVER, FLAG_NOLIMIT);
  4354. } else {
  4355. getScriptEnv()->addTempItem(container);
  4356. container->setParent(VirtualCylinder::virtualCylinder);
  4357. }
  4358.  
  4359. pushUserdata<Container>(L, container);
  4360. setMetatable(L, -1, "Container");
  4361. return 1;
  4362. }
  4363.  
  4364. int LuaScriptInterface::luaGameCreateMonster(lua_State* L)
  4365. {
  4366. // Game.createMonster(monsterName, position[, extended = false[, force = false]])
  4367. Monster* monster = Monster::createMonster(getString(L, 1));
  4368. if (!monster) {
  4369. lua_pushnil(L);
  4370. return 1;
  4371. }
  4372.  
  4373. const Position& position = getPosition(L, 2);
  4374. bool extended = getBoolean(L, 3, false);
  4375. bool force = getBoolean(L, 4, false);
  4376. if (g_game.placeCreature(monster, position, extended, force)) {
  4377. pushUserdata<Monster>(L, monster);
  4378. setMetatable(L, -1, "Monster");
  4379. } else {
  4380. delete monster;
  4381. lua_pushnil(L);
  4382. }
  4383. return 1;
  4384. }
  4385.  
  4386. int LuaScriptInterface::luaGameCreateNpc(lua_State* L)
  4387. {
  4388. // Game.createNpc(npcName, position[, extended = false[, force = false]])
  4389. Npc* npc = Npc::createNpc(getString(L, 1));
  4390. if (!npc) {
  4391. lua_pushnil(L);
  4392. return 1;
  4393. }
  4394.  
  4395. const Position& position = getPosition(L, 2);
  4396. bool extended = getBoolean(L, 3, false);
  4397. bool force = getBoolean(L, 4, false);
  4398. if (g_game.placeCreature(npc, position, extended, force)) {
  4399. pushUserdata<Npc>(L, npc);
  4400. setMetatable(L, -1, "Npc");
  4401. } else {
  4402. delete npc;
  4403. lua_pushnil(L);
  4404. }
  4405. return 1;
  4406. }
  4407.  
  4408. int LuaScriptInterface::luaGameCreateTile(lua_State* L)
  4409. {
  4410. // Game.createTile(x, y, z[, isDynamic = false])
  4411. // Game.createTile(position[, isDynamic = false])
  4412. Position position;
  4413. bool isDynamic;
  4414. if (isTable(L, 1)) {
  4415. position = getPosition(L, 1);
  4416. isDynamic = getBoolean(L, 2, false);
  4417. } else {
  4418. position.x = getNumber<uint16_t>(L, 1);
  4419. position.y = getNumber<uint16_t>(L, 2);
  4420. position.z = getNumber<uint16_t>(L, 3);
  4421. isDynamic = getBoolean(L, 4, false);
  4422. }
  4423.  
  4424. Tile* tile = g_game.map.getTile(position);
  4425. if (!tile) {
  4426. if (isDynamic) {
  4427. tile = new DynamicTile(position.x, position.y, position.z);
  4428. } else {
  4429. tile = new StaticTile(position.x, position.y, position.z);
  4430. }
  4431.  
  4432. g_game.map.setTile(position, tile);
  4433. }
  4434.  
  4435. pushUserdata(L, tile);
  4436. setMetatable(L, -1, "Tile");
  4437. return 1;
  4438. }
  4439.  
  4440. int LuaScriptInterface::luaGameStartRaid(lua_State* L)
  4441. {
  4442. // Game.startRaid(raidName)
  4443. const std::string& raidName = getString(L, 1);
  4444.  
  4445. Raid* raid = g_game.raids.getRaidByName(raidName);
  4446. if (raid) {
  4447. raid->startRaid();
  4448. pushBoolean(L, true);
  4449. } else {
  4450. lua_pushnil(L);
  4451. }
  4452. return 1;
  4453. }
  4454.  
  4455. // Variant
  4456. int LuaScriptInterface::luaVariantCreate(lua_State* L)
  4457. {
  4458. // Variant(number or string or position or thing)
  4459. LuaVariant variant;
  4460. if (isUserdata(L, 2)) {
  4461. if (Thing* thing = getThing(L, 2)) {
  4462. variant.type = VARIANT_TARGETPOSITION;
  4463. variant.pos = thing->getPosition();
  4464. }
  4465. } else if (isTable(L, 2)) {
  4466. variant.type = VARIANT_POSITION;
  4467. variant.pos = getPosition(L, 2);
  4468. } else if (isNumber(L, 2)) {
  4469. variant.type = VARIANT_NUMBER;
  4470. variant.number = getNumber<uint32_t>(L, 2);
  4471. } else if (isString(L, 2)) {
  4472. variant.type = VARIANT_STRING;
  4473. variant.text = getString(L, 2);
  4474. }
  4475. pushVariant(L, variant);
  4476. return 1;
  4477. }
  4478.  
  4479. int LuaScriptInterface::luaVariantGetNumber(lua_State* L)
  4480. {
  4481. // Variant:getNumber()
  4482. const LuaVariant& variant = getVariant(L, 1);
  4483. if (variant.type == VARIANT_NUMBER) {
  4484. lua_pushnumber(L, variant.number);
  4485. } else {
  4486. lua_pushnumber(L, 0);
  4487. }
  4488. return 1;
  4489. }
  4490.  
  4491. int LuaScriptInterface::luaVariantGetString(lua_State* L)
  4492. {
  4493. // Variant:getString()
  4494. const LuaVariant& variant = getVariant(L, 1);
  4495. if (variant.type == VARIANT_STRING) {
  4496. pushString(L, variant.text);
  4497. } else {
  4498. pushString(L, std::string());
  4499. }
  4500. return 1;
  4501. }
  4502.  
  4503. int LuaScriptInterface::luaVariantGetPosition(lua_State* L)
  4504. {
  4505. // Variant:getPosition()
  4506. const LuaVariant& variant = getVariant(L, 1);
  4507. if (variant.type == VARIANT_POSITION || variant.type == VARIANT_TARGETPOSITION) {
  4508. pushPosition(L, variant.pos);
  4509. } else {
  4510. pushPosition(L, Position());
  4511. }
  4512. return 1;
  4513. }
  4514.  
  4515. // Position
  4516. int LuaScriptInterface::luaPositionCreate(lua_State* L)
  4517. {
  4518. // Position([x = 0[, y = 0[, z = 0[, stackpos = 0]]]])
  4519. // Position([position])
  4520. if (lua_gettop(L) <= 1) {
  4521. pushPosition(L, Position());
  4522. return 1;
  4523. }
  4524.  
  4525. int32_t stackpos;
  4526. if (isTable(L, 2)) {
  4527. const Position& position = getPosition(L, 2, stackpos);
  4528. pushPosition(L, position, stackpos);
  4529. } else {
  4530. uint16_t x = getNumber<uint16_t>(L, 2, 0);
  4531. uint16_t y = getNumber<uint16_t>(L, 3, 0);
  4532. uint8_t z = getNumber<uint8_t>(L, 4, 0);
  4533. stackpos = getNumber<int32_t>(L, 5, 0);
  4534.  
  4535. pushPosition(L, Position(x, y, z), stackpos);
  4536. }
  4537. return 1;
  4538. }
  4539.  
  4540. int LuaScriptInterface::luaPositionAdd(lua_State* L)
  4541. {
  4542. // positionValue = position + positionEx
  4543. int32_t stackpos;
  4544. const Position& position = getPosition(L, 1, stackpos);
  4545.  
  4546. Position positionEx;
  4547. if (stackpos == 0) {
  4548. positionEx = getPosition(L, 2, stackpos);
  4549. } else {
  4550. positionEx = getPosition(L, 2);
  4551. }
  4552.  
  4553. pushPosition(L, position + positionEx, stackpos);
  4554. return 1;
  4555. }
  4556.  
  4557. int LuaScriptInterface::luaPositionSub(lua_State* L)
  4558. {
  4559. // positionValue = position - positionEx
  4560. int32_t stackpos;
  4561. const Position& position = getPosition(L, 1, stackpos);
  4562.  
  4563. Position positionEx;
  4564. if (stackpos == 0) {
  4565. positionEx = getPosition(L, 2, stackpos);
  4566. } else {
  4567. positionEx = getPosition(L, 2);
  4568. }
  4569.  
  4570. pushPosition(L, position - positionEx, stackpos);
  4571. return 1;
  4572. }
  4573.  
  4574. int LuaScriptInterface::luaPositionCompare(lua_State* L)
  4575. {
  4576. // position == positionEx
  4577. const Position& positionEx = getPosition(L, 2);
  4578. const Position& position = getPosition(L, 1);
  4579. pushBoolean(L, position == positionEx);
  4580. return 1;
  4581. }
  4582.  
  4583. int LuaScriptInterface::luaPositionGetDistance(lua_State* L)
  4584. {
  4585. // position:getDistance(positionEx)
  4586. const Position& positionEx = getPosition(L, 2);
  4587. const Position& position = getPosition(L, 1);
  4588. lua_pushnumber(L, std::max<int32_t>(
  4589. std::max<int32_t>(
  4590. std::abs(Position::getDistanceX(position, positionEx)),
  4591. std::abs(Position::getDistanceY(position, positionEx))
  4592. ),
  4593. std::abs(Position::getDistanceZ(position, positionEx))
  4594. ));
  4595. return 1;
  4596. }
  4597.  
  4598. int LuaScriptInterface::luaPositionIsSightClear(lua_State* L)
  4599. {
  4600. // position:isSightClear(positionEx[, sameFloor = true])
  4601. bool sameFloor = getBoolean(L, 3, true);
  4602. const Position& positionEx = getPosition(L, 2);
  4603. const Position& position = getPosition(L, 1);
  4604. pushBoolean(L, g_game.isSightClear(position, positionEx, sameFloor));
  4605. return 1;
  4606. }
  4607.  
  4608. int LuaScriptInterface::luaPositionSendMagicEffect(lua_State* L)
  4609. {
  4610. // position:sendMagicEffect(magicEffect[, player = nullptr])
  4611. SpectatorVec list;
  4612. if (lua_gettop(L) >= 3) {
  4613. Player* player = getPlayer(L, 3);
  4614. if (player) {
  4615. list.insert(player);
  4616. }
  4617. }
  4618.  
  4619. MagicEffectClasses magicEffect = getNumber<MagicEffectClasses>(L, 2);
  4620. const Position& position = getPosition(L, 1);
  4621. if (!list.empty()) {
  4622. Game::addMagicEffect(list, position, magicEffect);
  4623. } else {
  4624. g_game.addMagicEffect(position, magicEffect);
  4625. }
  4626.  
  4627. pushBoolean(L, true);
  4628. return 1;
  4629. }
  4630.  
  4631. int LuaScriptInterface::luaPositionSendDistanceEffect(lua_State* L)
  4632. {
  4633. // position:sendDistanceEffect(positionEx, distanceEffect[, player = nullptr])
  4634. SpectatorVec list;
  4635. if (lua_gettop(L) >= 4) {
  4636. Player* player = getPlayer(L, 4);
  4637. if (player) {
  4638. list.insert(player);
  4639. }
  4640. }
  4641.  
  4642. ShootType_t distanceEffect = getNumber<ShootType_t>(L, 3);
  4643. const Position& positionEx = getPosition(L, 2);
  4644. const Position& position = getPosition(L, 1);
  4645. if (!list.empty()) {
  4646. Game::addDistanceEffect(list, position, positionEx, distanceEffect);
  4647. } else {
  4648. g_game.addDistanceEffect(position, positionEx, distanceEffect);
  4649. }
  4650.  
  4651. pushBoolean(L, true);
  4652. return 1;
  4653. }
  4654.  
  4655. // Tile
  4656. int LuaScriptInterface::luaTileCreate(lua_State* L)
  4657. {
  4658. // Tile(x, y, z)
  4659. // Tile(position)
  4660. Tile* tile;
  4661. if (isTable(L, 2)) {
  4662. tile = g_game.map.getTile(getPosition(L, 2));
  4663. } else {
  4664. uint8_t z = getNumber<uint8_t>(L, 4);
  4665. uint16_t y = getNumber<uint16_t>(L, 3);
  4666. uint16_t x = getNumber<uint16_t>(L, 2);
  4667. tile = g_game.map.getTile(x, y, z);
  4668. }
  4669.  
  4670. if (tile) {
  4671. pushUserdata<Tile>(L, tile);
  4672. setMetatable(L, -1, "Tile");
  4673. } else {
  4674. lua_pushnil(L);
  4675. }
  4676. return 1;
  4677. }
  4678.  
  4679. int LuaScriptInterface::luaTileGetPosition(lua_State* L)
  4680. {
  4681. // tile:getPosition()
  4682. Tile* tile = getUserdata<Tile>(L, 1);
  4683. if (tile) {
  4684. pushPosition(L, tile->getPosition());
  4685. } else {
  4686. lua_pushnil(L);
  4687. }
  4688. return 1;
  4689. }
  4690.  
  4691. int LuaScriptInterface::luaTileGetGround(lua_State* L)
  4692. {
  4693. // tile:getGround()
  4694. Tile* tile = getUserdata<Tile>(L, 1);
  4695. if (tile && tile->getGround()) {
  4696. pushUserdata<Item>(L, tile->getGround());
  4697. setItemMetatable(L, -1, tile->getGround());
  4698. } else {
  4699. lua_pushnil(L);
  4700. }
  4701. return 1;
  4702. }
  4703.  
  4704. int LuaScriptInterface::luaTileGetThing(lua_State* L)
  4705. {
  4706. // tile:getThing(index)
  4707. int32_t index = getNumber<int32_t>(L, 2);
  4708. Tile* tile = getUserdata<Tile>(L, 1);
  4709. if (!tile) {
  4710. lua_pushnil(L);
  4711. return 1;
  4712. }
  4713.  
  4714. Thing* thing = tile->getThing(index);
  4715. if (!thing) {
  4716. lua_pushnil(L);
  4717. return 1;
  4718. }
  4719.  
  4720. if (Creature* creature = thing->getCreature()) {
  4721. pushUserdata<Creature>(L, creature);
  4722. setCreatureMetatable(L, -1, creature);
  4723. } else if (Item* item = thing->getItem()) {
  4724. pushUserdata<Item>(L, item);
  4725. setItemMetatable(L, -1, item);
  4726. } else {
  4727. lua_pushnil(L);
  4728. }
  4729. return 1;
  4730. }
  4731.  
  4732. int LuaScriptInterface::luaTileGetThingCount(lua_State* L)
  4733. {
  4734. // tile:getThingCount()
  4735. Tile* tile = getUserdata<Tile>(L, 1);
  4736. if (tile) {
  4737. lua_pushnumber(L, tile->getThingCount());
  4738. } else {
  4739. lua_pushnil(L);
  4740. }
  4741. return 1;
  4742. }
  4743.  
  4744. int LuaScriptInterface::luaTileGetTopVisibleThing(lua_State* L)
  4745. {
  4746. // tile:getTopVisibleThing(creature)
  4747. Creature* creature = getCreature(L, 2);
  4748. Tile* tile = getUserdata<Tile>(L, 1);
  4749. if (!tile) {
  4750. lua_pushnil(L);
  4751. return 1;
  4752. }
  4753.  
  4754. Thing* thing = tile->getTopVisibleThing(creature);
  4755. if (!thing) {
  4756. lua_pushnil(L);
  4757. return 1;
  4758. }
  4759.  
  4760. if (Creature* visibleCreature = thing->getCreature()) {
  4761. pushUserdata<Creature>(L, visibleCreature);
  4762. setCreatureMetatable(L, -1, visibleCreature);
  4763. } else if (Item* visibleItem = thing->getItem()) {
  4764. pushUserdata<Item>(L, visibleItem);
  4765. setItemMetatable(L, -1, visibleItem);
  4766. } else {
  4767. lua_pushnil(L);
  4768. }
  4769. return 1;
  4770. }
  4771.  
  4772. int LuaScriptInterface::luaTileGetTopTopItem(lua_State* L)
  4773. {
  4774. // tile:getTopTopItem()
  4775. Tile* tile = getUserdata<Tile>(L, 1);
  4776. if (!tile) {
  4777. lua_pushnil(L);
  4778. return 1;
  4779. }
  4780.  
  4781. Item* item = tile->getTopTopItem();
  4782. if (item) {
  4783. pushUserdata<Item>(L, item);
  4784. setItemMetatable(L, -1, item);
  4785. } else {
  4786. lua_pushnil(L);
  4787. }
  4788. return 1;
  4789. }
  4790.  
  4791. int LuaScriptInterface::luaTileGetTopDownItem(lua_State* L)
  4792. {
  4793. // tile:getTopDownItem()
  4794. Tile* tile = getUserdata<Tile>(L, 1);
  4795. if (!tile) {
  4796. lua_pushnil(L);
  4797. return 1;
  4798. }
  4799.  
  4800. Item* item = tile->getTopDownItem();
  4801. if (item) {
  4802. pushUserdata<Item>(L, item);
  4803. setItemMetatable(L, -1, item);
  4804. } else {
  4805. lua_pushnil(L);
  4806. }
  4807. return 1;
  4808. }
  4809.  
  4810. int LuaScriptInterface::luaTileGetFieldItem(lua_State* L)
  4811. {
  4812. // tile:getFieldItem()
  4813. Tile* tile = getUserdata<Tile>(L, 1);
  4814. if (!tile) {
  4815. lua_pushnil(L);
  4816. return 1;
  4817. }
  4818.  
  4819. Item* item = tile->getFieldItem();
  4820. if (item) {
  4821. pushUserdata<Item>(L, item);
  4822. setItemMetatable(L, -1, item);
  4823. } else {
  4824. lua_pushnil(L);
  4825. }
  4826. return 1;
  4827. }
  4828.  
  4829. int LuaScriptInterface::luaTileGetItemById(lua_State* L)
  4830. {
  4831. // tile:getItemById(itemId[, subType = -1])
  4832. Tile* tile = getUserdata<Tile>(L, 1);
  4833. if (!tile) {
  4834. lua_pushnil(L);
  4835. return 1;
  4836. }
  4837.  
  4838. uint16_t itemId;
  4839. if (isNumber(L, 2)) {
  4840. itemId = getNumber<uint16_t>(L, 2);
  4841. } else {
  4842. itemId = Item::items.getItemIdByName(getString(L, 2));
  4843. if (itemId == 0) {
  4844. lua_pushnil(L);
  4845. return 1;
  4846. }
  4847. }
  4848. int32_t subType = getNumber<int32_t>(L, 3, -1);
  4849.  
  4850. Item* item = g_game.findItemOfType(tile, itemId, false, subType);
  4851. if (item) {
  4852. pushUserdata<Item>(L, item);
  4853. setItemMetatable(L, -1, item);
  4854. } else {
  4855. lua_pushnil(L);
  4856. }
  4857. return 1;
  4858. }
  4859.  
  4860. int LuaScriptInterface::luaTileGetItemByType(lua_State* L)
  4861. {
  4862. // tile:getItemByType(itemType)
  4863. Tile* tile = getUserdata<Tile>(L, 1);
  4864. if (!tile) {
  4865. lua_pushnil(L);
  4866. return 1;
  4867. }
  4868.  
  4869. bool found;
  4870.  
  4871. ItemTypes_t itemType = getNumber<ItemTypes_t>(L, 2);
  4872. switch (itemType) {
  4873. case ITEM_TYPE_TELEPORT:
  4874. found = tile->hasFlag(TILESTATE_TELEPORT);
  4875. break;
  4876. case ITEM_TYPE_MAGICFIELD:
  4877. found = tile->hasFlag(TILESTATE_MAGICFIELD);
  4878. break;
  4879. case ITEM_TYPE_MAILBOX:
  4880. found = tile->hasFlag(TILESTATE_MAILBOX);
  4881. break;
  4882. case ITEM_TYPE_TRASHHOLDER:
  4883. found = tile->hasFlag(TILESTATE_TRASHHOLDER);
  4884. break;
  4885. case ITEM_TYPE_BED:
  4886. found = tile->hasFlag(TILESTATE_BED);
  4887. break;
  4888. case ITEM_TYPE_DEPOT:
  4889. found = tile->hasFlag(TILESTATE_DEPOT);
  4890. break;
  4891. default:
  4892. found = true;
  4893. break;
  4894. }
  4895.  
  4896. if (!found) {
  4897. lua_pushnil(L);
  4898. return 1;
  4899. }
  4900.  
  4901. if (Item* item = tile->getGround()) {
  4902. const ItemType& it = Item::items[item->getID()];
  4903. if (it.type == itemType) {
  4904. pushUserdata<Item>(L, item);
  4905. setItemMetatable(L, -1, item);
  4906. return 1;
  4907. }
  4908. }
  4909.  
  4910. if (const TileItemVector* items = tile->getItemList()) {
  4911. for (Item* item : *items) {
  4912. const ItemType& it = Item::items[item->getID()];
  4913. if (it.type == itemType) {
  4914. pushUserdata<Item>(L, item);
  4915. setItemMetatable(L, -1, item);
  4916. return 1;
  4917. }
  4918. }
  4919. }
  4920.  
  4921. lua_pushnil(L);
  4922. return 1;
  4923. }
  4924.  
  4925. int LuaScriptInterface::luaTileGetItemByTopOrder(lua_State* L)
  4926. {
  4927. // tile:getItemByTopOrder(topOrder)
  4928. Tile* tile = getUserdata<Tile>(L, 1);
  4929. if (!tile) {
  4930. lua_pushnil(L);
  4931. return 1;
  4932. }
  4933.  
  4934. int32_t topOrder = getNumber<int32_t>(L, 2);
  4935.  
  4936. Item* item = tile->getItemByTopOrder(topOrder);
  4937. if (!item) {
  4938. lua_pushnil(L);
  4939. return 1;
  4940. }
  4941.  
  4942. pushUserdata<Item>(L, item);
  4943. setItemMetatable(L, -1, item);
  4944. return 1;
  4945. }
  4946.  
  4947. int LuaScriptInterface::luaTileGetItemCountById(lua_State* L)
  4948. {
  4949. // tile:getItemCountById(itemId[, subType = -1])
  4950. Tile* tile = getUserdata<Tile>(L, 1);
  4951. if (!tile) {
  4952. lua_pushnil(L);
  4953. return 1;
  4954. }
  4955.  
  4956. int32_t subType = getNumber<int32_t>(L, 3, -1);
  4957.  
  4958. uint16_t itemId;
  4959. if (isNumber(L, 2)) {
  4960. itemId = getNumber<uint16_t>(L, 2);
  4961. } else {
  4962. itemId = Item::items.getItemIdByName(getString(L, 2));
  4963. if (itemId == 0) {
  4964. lua_pushnil(L);
  4965. return 1;
  4966. }
  4967. }
  4968.  
  4969. lua_pushnumber(L, tile->getItemTypeCount(itemId, subType));
  4970. return 1;
  4971. }
  4972.  
  4973. int LuaScriptInterface::luaTileGetBottomCreature(lua_State* L)
  4974. {
  4975. // tile:getBottomCreature()
  4976. Tile* tile = getUserdata<Tile>(L, 1);
  4977. if (!tile) {
  4978. lua_pushnil(L);
  4979. return 1;
  4980. }
  4981.  
  4982. const Creature* creature = tile->getBottomCreature();
  4983. if (!creature) {
  4984. lua_pushnil(L);
  4985. return 1;
  4986. }
  4987.  
  4988. pushUserdata<const Creature>(L, creature);
  4989. setCreatureMetatable(L, -1, creature);
  4990. return 1;
  4991. }
  4992.  
  4993. int LuaScriptInterface::luaTileGetTopCreature(lua_State* L)
  4994. {
  4995. // tile:getTopCreature()
  4996. Tile* tile = getUserdata<Tile>(L, 1);
  4997. if (!tile) {
  4998. lua_pushnil(L);
  4999. return 1;
  5000. }
  5001.  
  5002. Creature* creature = tile->getTopCreature();
  5003. if (!creature) {
  5004. lua_pushnil(L);
  5005. return 1;
  5006. }
  5007.  
  5008. pushUserdata<Creature>(L, creature);
  5009. setCreatureMetatable(L, -1, creature);
  5010. return 1;
  5011. }
  5012.  
  5013. int LuaScriptInterface::luaTileGetBottomVisibleCreature(lua_State* L)
  5014. {
  5015. // tile:getBottomVisibleCreature(creature)
  5016. Tile* tile = getUserdata<Tile>(L, 1);
  5017. if (!tile) {
  5018. lua_pushnil(L);
  5019. return 1;
  5020. }
  5021.  
  5022. Creature* creature = getCreature(L, 2);
  5023. if (!creature) {
  5024. lua_pushnil(L);
  5025. return 1;
  5026. }
  5027.  
  5028. const Creature* visibleCreature = tile->getBottomVisibleCreature(creature);
  5029. if (visibleCreature) {
  5030. pushUserdata<const Creature>(L, visibleCreature);
  5031. setCreatureMetatable(L, -1, visibleCreature);
  5032. } else {
  5033. lua_pushnil(L);
  5034. }
  5035. return 1;
  5036. }
  5037.  
  5038. int LuaScriptInterface::luaTileGetTopVisibleCreature(lua_State* L)
  5039. {
  5040. // tile:getTopVisibleCreature(creature)
  5041. Tile* tile = getUserdata<Tile>(L, 1);
  5042. if (!tile) {
  5043. lua_pushnil(L);
  5044. return 1;
  5045. }
  5046.  
  5047. Creature* creature = getCreature(L, 2);
  5048. if (!creature) {
  5049. lua_pushnil(L);
  5050. return 1;
  5051. }
  5052.  
  5053. Creature* visibleCreature = tile->getTopVisibleCreature(creature);
  5054. if (visibleCreature) {
  5055. pushUserdata<Creature>(L, visibleCreature);
  5056. setCreatureMetatable(L, -1, visibleCreature);
  5057. } else {
  5058. lua_pushnil(L);
  5059. }
  5060. return 1;
  5061. }
  5062.  
  5063. int LuaScriptInterface::luaTileGetItems(lua_State* L)
  5064. {
  5065. // tile:getItems()
  5066. Tile* tile = getUserdata<Tile>(L, 1);
  5067. if (!tile) {
  5068. lua_pushnil(L);
  5069. return 1;
  5070. }
  5071.  
  5072. TileItemVector* itemVector = tile->getItemList();
  5073. if (!itemVector) {
  5074. lua_pushnil(L);
  5075. return 1;
  5076. }
  5077.  
  5078. lua_createtable(L, itemVector->size(), 0);
  5079.  
  5080. int index = 0;
  5081. for (Item* item : *itemVector) {
  5082. pushUserdata<Item>(L, item);
  5083. setItemMetatable(L, -1, item);
  5084. lua_rawseti(L, -2, ++index);
  5085. }
  5086. return 1;
  5087. }
  5088.  
  5089. int LuaScriptInterface::luaTileGetItemCount(lua_State* L)
  5090. {
  5091. // tile:getItemCount()
  5092. Tile* tile = getUserdata<Tile>(L, 1);
  5093. if (!tile) {
  5094. lua_pushnil(L);
  5095. return 1;
  5096. }
  5097.  
  5098. lua_pushnumber(L, tile->getItemCount());
  5099. return 1;
  5100. }
  5101.  
  5102. int LuaScriptInterface::luaTileGetDownItemCount(lua_State* L)
  5103. {
  5104. // tile:getDownItemCount()
  5105. Tile* tile = getUserdata<Tile>(L, 1);
  5106. if (tile) {
  5107. lua_pushnumber(L, tile->getDownItemCount());
  5108. } else {
  5109. lua_pushnil(L);
  5110. }
  5111. return 1;
  5112. }
  5113.  
  5114. int LuaScriptInterface::luaTileGetTopItemCount(lua_State* L)
  5115. {
  5116. // tile:getTopItemCount()
  5117. Tile* tile = getUserdata<Tile>(L, 1);
  5118. if (!tile) {
  5119. lua_pushnil(L);
  5120. return 1;
  5121. }
  5122.  
  5123. lua_pushnumber(L, tile->getTopItemCount());
  5124. return 1;
  5125. }
  5126.  
  5127. int LuaScriptInterface::luaTileGetCreatures(lua_State* L)
  5128. {
  5129. // tile:getCreatures()
  5130. Tile* tile = getUserdata<Tile>(L, 1);
  5131. if (!tile) {
  5132. lua_pushnil(L);
  5133. return 1;
  5134. }
  5135.  
  5136. CreatureVector* creatureVector = tile->getCreatures();
  5137. if (!creatureVector) {
  5138. lua_pushnil(L);
  5139. return 1;
  5140. }
  5141.  
  5142. lua_createtable(L, creatureVector->size(), 0);
  5143.  
  5144. int index = 0;
  5145. for (Creature* creature : *creatureVector) {
  5146. pushUserdata<Creature>(L, creature);
  5147. setCreatureMetatable(L, -1, creature);
  5148. lua_rawseti(L, -2, ++index);
  5149. }
  5150. return 1;
  5151. }
  5152.  
  5153. int LuaScriptInterface::luaTileGetCreatureCount(lua_State* L)
  5154. {
  5155. // tile:getCreatureCount()
  5156. Tile* tile = getUserdata<Tile>(L, 1);
  5157. if (!tile) {
  5158. lua_pushnil(L);
  5159. return 1;
  5160. }
  5161.  
  5162. lua_pushnumber(L, tile->getCreatureCount());
  5163. return 1;
  5164. }
  5165.  
  5166. int LuaScriptInterface::luaTileHasProperty(lua_State* L)
  5167. {
  5168. // tile:hasProperty(property[, item])
  5169. Tile* tile = getUserdata<Tile>(L, 1);
  5170. if (!tile) {
  5171. lua_pushnil(L);
  5172. return 1;
  5173. }
  5174.  
  5175. Item* item;
  5176. if (lua_gettop(L) >= 3) {
  5177. item = getUserdata<Item>(L, 3);
  5178. } else {
  5179. item = nullptr;
  5180. }
  5181.  
  5182. ITEMPROPERTY property = getNumber<ITEMPROPERTY>(L, 2);
  5183. if (item) {
  5184. pushBoolean(L, tile->hasProperty(item, property));
  5185. } else {
  5186. pushBoolean(L, tile->hasProperty(property));
  5187. }
  5188. return 1;
  5189. }
  5190.  
  5191. int LuaScriptInterface::luaTileGetThingIndex(lua_State* L)
  5192. {
  5193. // tile:getThingIndex(thing)
  5194. Tile* tile = getUserdata<Tile>(L, 1);
  5195. if (!tile) {
  5196. lua_pushnil(L);
  5197. return 1;
  5198. }
  5199.  
  5200. Thing* thing = getThing(L, 2);
  5201. if (thing) {
  5202. lua_pushnumber(L, tile->getThingIndex(thing));
  5203. } else {
  5204. lua_pushnil(L);
  5205. }
  5206. return 1;
  5207. }
  5208.  
  5209. int LuaScriptInterface::luaTileHasFlag(lua_State* L)
  5210. {
  5211. // tile:hasFlag(flag)
  5212. Tile* tile = getUserdata<Tile>(L, 1);
  5213. if (tile) {
  5214. tileflags_t flag = getNumber<tileflags_t>(L, 2);
  5215. pushBoolean(L, tile->hasFlag(flag));
  5216. } else {
  5217. lua_pushnil(L);
  5218. }
  5219. return 1;
  5220. }
  5221.  
  5222. int LuaScriptInterface::luaTileQueryAdd(lua_State* L)
  5223. {
  5224. // tile:queryAdd(thing[, flags])
  5225. Tile* tile = getUserdata<Tile>(L, 1);
  5226. if (!tile) {
  5227. lua_pushnil(L);
  5228. return 1;
  5229. }
  5230.  
  5231. Thing* thing = getThing(L, 2);
  5232. if (thing) {
  5233. uint32_t flags = getNumber<uint32_t>(L, 3, 0);
  5234. lua_pushnumber(L, tile->queryAdd(0, *thing, 1, flags));
  5235. } else {
  5236. lua_pushnil(L);
  5237. }
  5238. return 1;
  5239. }
  5240.  
  5241. int LuaScriptInterface::luaTileGetHouse(lua_State* L)
  5242. {
  5243. // tile:getHouse()
  5244. Tile* tile = getUserdata<Tile>(L, 1);
  5245. if (!tile) {
  5246. lua_pushnil(L);
  5247. return 1;
  5248. }
  5249.  
  5250. if (HouseTile* houseTile = dynamic_cast<HouseTile*>(tile)) {
  5251. pushUserdata<House>(L, houseTile->getHouse());
  5252. setMetatable(L, -1, "House");
  5253. } else {
  5254. lua_pushnil(L);
  5255. }
  5256. return 1;
  5257. }
  5258.  
  5259. // NetworkMessage
  5260. int LuaScriptInterface::luaNetworkMessageCreate(lua_State* L)
  5261. {
  5262. // NetworkMessage()
  5263. pushUserdata<NetworkMessage>(L, new NetworkMessage);
  5264. setMetatable(L, -1, "NetworkMessage");
  5265. return 1;
  5266. }
  5267.  
  5268. int LuaScriptInterface::luaNetworkMessageDelete(lua_State* L)
  5269. {
  5270. NetworkMessage** messagePtr = getRawUserdata<NetworkMessage>(L, 1);
  5271. if (messagePtr && *messagePtr) {
  5272. delete *messagePtr;
  5273. *messagePtr = nullptr;
  5274. }
  5275. return 0;
  5276. }
  5277.  
  5278. int LuaScriptInterface::luaNetworkMessageGetByte(lua_State* L)
  5279. {
  5280. // networkMessage:getByte()
  5281. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5282. if (message) {
  5283. lua_pushnumber(L, message->getByte());
  5284. } else {
  5285. lua_pushnil(L);
  5286. }
  5287. return 1;
  5288. }
  5289.  
  5290. int LuaScriptInterface::luaNetworkMessageGetU16(lua_State* L)
  5291. {
  5292. // networkMessage:getU16()
  5293. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5294. if (message) {
  5295. lua_pushnumber(L, message->get<uint16_t>());
  5296. } else {
  5297. lua_pushnil(L);
  5298. }
  5299. return 1;
  5300. }
  5301.  
  5302. int LuaScriptInterface::luaNetworkMessageGetU32(lua_State* L)
  5303. {
  5304. // networkMessage:getU32()
  5305. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5306. if (message) {
  5307. lua_pushnumber(L, message->get<uint32_t>());
  5308. } else {
  5309. lua_pushnil(L);
  5310. }
  5311. return 1;
  5312. }
  5313.  
  5314. int LuaScriptInterface::luaNetworkMessageGetU64(lua_State* L)
  5315. {
  5316. // networkMessage:getU64()
  5317. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5318. if (message) {
  5319. lua_pushnumber(L, message->get<uint64_t>());
  5320. } else {
  5321. lua_pushnil(L);
  5322. }
  5323. return 1;
  5324. }
  5325.  
  5326. int LuaScriptInterface::luaNetworkMessageGetString(lua_State* L)
  5327. {
  5328. // networkMessage:getString()
  5329. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5330. if (message) {
  5331. pushString(L, message->getString());
  5332. } else {
  5333. lua_pushnil(L);
  5334. }
  5335. return 1;
  5336. }
  5337.  
  5338. int LuaScriptInterface::luaNetworkMessageGetPosition(lua_State* L)
  5339. {
  5340. // networkMessage:getPosition()
  5341. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5342. if (message) {
  5343. pushPosition(L, message->getPosition());
  5344. } else {
  5345. lua_pushnil(L);
  5346. }
  5347. return 1;
  5348. }
  5349.  
  5350. int LuaScriptInterface::luaNetworkMessageAddByte(lua_State* L)
  5351. {
  5352. // networkMessage:addByte(number)
  5353. uint8_t number = getNumber<uint8_t>(L, 2);
  5354. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5355. if (message) {
  5356. message->addByte(number);
  5357. pushBoolean(L, true);
  5358. } else {
  5359. lua_pushnil(L);
  5360. }
  5361. return 1;
  5362. }
  5363.  
  5364. int LuaScriptInterface::luaNetworkMessageAddU16(lua_State* L)
  5365. {
  5366. // networkMessage:addU16(number)
  5367. uint16_t number = getNumber<uint16_t>(L, 2);
  5368. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5369. if (message) {
  5370. message->add<uint16_t>(number);
  5371. pushBoolean(L, true);
  5372. } else {
  5373. lua_pushnil(L);
  5374. }
  5375. return 1;
  5376. }
  5377.  
  5378. int LuaScriptInterface::luaNetworkMessageAddU32(lua_State* L)
  5379. {
  5380. // networkMessage:addU32(number)
  5381. uint32_t number = getNumber<uint32_t>(L, 2);
  5382. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5383. if (message) {
  5384. message->add<uint32_t>(number);
  5385. pushBoolean(L, true);
  5386. } else {
  5387. lua_pushnil(L);
  5388. }
  5389. return 1;
  5390. }
  5391.  
  5392. int LuaScriptInterface::luaNetworkMessageAddU64(lua_State* L)
  5393. {
  5394. // networkMessage:addU64(number)
  5395. uint64_t number = getNumber<uint64_t>(L, 2);
  5396. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5397. if (message) {
  5398. message->add<uint64_t>(number);
  5399. pushBoolean(L, true);
  5400. } else {
  5401. lua_pushnil(L);
  5402. }
  5403. return 1;
  5404. }
  5405.  
  5406. int LuaScriptInterface::luaNetworkMessageAddString(lua_State* L)
  5407. {
  5408. // networkMessage:addString(string)
  5409. const std::string& string = getString(L, 2);
  5410. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5411. if (message) {
  5412. message->addString(string);
  5413. pushBoolean(L, true);
  5414. } else {
  5415. lua_pushnil(L);
  5416. }
  5417. return 1;
  5418. }
  5419.  
  5420. int LuaScriptInterface::luaNetworkMessageAddPosition(lua_State* L)
  5421. {
  5422. // networkMessage:addPosition(position)
  5423. const Position& position = getPosition(L, 2);
  5424. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5425. if (message) {
  5426. message->addPosition(position);
  5427. pushBoolean(L, true);
  5428. } else {
  5429. lua_pushnil(L);
  5430. }
  5431. return 1;
  5432. }
  5433.  
  5434. int LuaScriptInterface::luaNetworkMessageAddDouble(lua_State* L)
  5435. {
  5436. // networkMessage:addDouble(number)
  5437. double number = getNumber<double>(L, 2);
  5438. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5439. if (message) {
  5440. message->addDouble(number);
  5441. pushBoolean(L, true);
  5442. } else {
  5443. lua_pushnil(L);
  5444. }
  5445. return 1;
  5446. }
  5447.  
  5448. int LuaScriptInterface::luaNetworkMessageAddItem(lua_State* L)
  5449. {
  5450. // networkMessage:addItem(item)
  5451. Item* item = getUserdata<Item>(L, 2);
  5452. if (!item) {
  5453. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  5454. lua_pushnil(L);
  5455. return 1;
  5456. }
  5457.  
  5458. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5459. if (message) {
  5460. message->addItem(item);
  5461. pushBoolean(L, true);
  5462. } else {
  5463. lua_pushnil(L);
  5464. }
  5465. return 1;
  5466. }
  5467.  
  5468. int LuaScriptInterface::luaNetworkMessageAddItemId(lua_State* L)
  5469. {
  5470. // networkMessage:addItemId(itemId)
  5471. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5472. if (!message) {
  5473. lua_pushnil(L);
  5474. return 1;
  5475. }
  5476.  
  5477. uint16_t itemId;
  5478. if (isNumber(L, 2)) {
  5479. itemId = getNumber<uint16_t>(L, 2);
  5480. } else {
  5481. itemId = Item::items.getItemIdByName(getString(L, 2));
  5482. if (itemId == 0) {
  5483. lua_pushnil(L);
  5484. return 1;
  5485. }
  5486. }
  5487.  
  5488. message->addItemId(itemId);
  5489. pushBoolean(L, true);
  5490. return 1;
  5491. }
  5492.  
  5493. int LuaScriptInterface::luaNetworkMessageReset(lua_State* L)
  5494. {
  5495. // networkMessage:reset()
  5496. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5497. if (message) {
  5498. message->reset();
  5499. pushBoolean(L, true);
  5500. } else {
  5501. lua_pushnil(L);
  5502. }
  5503. return 1;
  5504. }
  5505.  
  5506. int LuaScriptInterface::luaNetworkMessageSkipBytes(lua_State* L)
  5507. {
  5508. // networkMessage:skipBytes(number)
  5509. int16_t number = getNumber<int16_t>(L, 2);
  5510. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5511. if (message) {
  5512. message->skipBytes(number);
  5513. pushBoolean(L, true);
  5514. } else {
  5515. lua_pushnil(L);
  5516. }
  5517. return 1;
  5518. }
  5519.  
  5520. int LuaScriptInterface::luaNetworkMessageSendToPlayer(lua_State* L)
  5521. {
  5522. // networkMessage:sendToPlayer(player[, broadcast])
  5523. NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5524. if (!message) {
  5525. lua_pushnil(L);
  5526. return 1;
  5527. }
  5528.  
  5529. Player* player = getPlayer(L, 2);
  5530. if (player) {
  5531. bool broadcast = getBoolean(L, 3, true);
  5532. player->sendNetworkMessage(*message, broadcast);
  5533. pushBoolean(L, true);
  5534. } else {
  5535. reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  5536. lua_pushnil(L);
  5537. }
  5538. return 1;
  5539. }
  5540.  
  5541. // ModalWindow
  5542. int LuaScriptInterface::luaModalWindowCreate(lua_State* L)
  5543. {
  5544. // ModalWindow(id, title, message)
  5545. const std::string& message = getString(L, 4);
  5546. const std::string& title = getString(L, 3);
  5547. uint32_t id = getNumber<uint32_t>(L, 2);
  5548.  
  5549. pushUserdata<ModalWindow>(L, new ModalWindow(id, title, message));
  5550. setMetatable(L, -1, "ModalWindow");
  5551. return 1;
  5552. }
  5553.  
  5554. int LuaScriptInterface::luaModalWindowDelete(lua_State* L)
  5555. {
  5556. ModalWindow** windowPtr = getRawUserdata<ModalWindow>(L, 1);
  5557. if (windowPtr && *windowPtr) {
  5558. delete *windowPtr;
  5559. *windowPtr = nullptr;
  5560. }
  5561. return 0;
  5562. }
  5563.  
  5564. int LuaScriptInterface::luaModalWindowGetId(lua_State* L)
  5565. {
  5566. // modalWindow:getId()
  5567. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5568. if (window) {
  5569. lua_pushnumber(L, window->id);
  5570. } else {
  5571. lua_pushnil(L);
  5572. }
  5573. return 1;
  5574. }
  5575.  
  5576. int LuaScriptInterface::luaModalWindowGetTitle(lua_State* L)
  5577. {
  5578. // modalWindow:getTitle()
  5579. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5580. if (window) {
  5581. pushString(L, window->title);
  5582. } else {
  5583. lua_pushnil(L);
  5584. }
  5585. return 1;
  5586. }
  5587.  
  5588. int LuaScriptInterface::luaModalWindowGetMessage(lua_State* L)
  5589. {
  5590. // modalWindow:getMessage()
  5591. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5592. if (window) {
  5593. pushString(L, window->message);
  5594. } else {
  5595. lua_pushnil(L);
  5596. }
  5597. return 1;
  5598. }
  5599.  
  5600. int LuaScriptInterface::luaModalWindowSetTitle(lua_State* L)
  5601. {
  5602. // modalWindow:setTitle(text)
  5603. const std::string& text = getString(L, 2);
  5604. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5605. if (window) {
  5606. window->title = text;
  5607. pushBoolean(L, true);
  5608. } else {
  5609. lua_pushnil(L);
  5610. }
  5611. return 1;
  5612. }
  5613.  
  5614. int LuaScriptInterface::luaModalWindowSetMessage(lua_State* L)
  5615. {
  5616. // modalWindow:setMessage(text)
  5617. const std::string& text = getString(L, 2);
  5618. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5619. if (window) {
  5620. window->message = text;
  5621. pushBoolean(L, true);
  5622. } else {
  5623. lua_pushnil(L);
  5624. }
  5625. return 1;
  5626. }
  5627.  
  5628. int LuaScriptInterface::luaModalWindowGetButtonCount(lua_State* L)
  5629. {
  5630. // modalWindow:getButtonCount()
  5631. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5632. if (window) {
  5633. lua_pushnumber(L, window->buttons.size());
  5634. } else {
  5635. lua_pushnil(L);
  5636. }
  5637. return 1;
  5638. }
  5639.  
  5640. int LuaScriptInterface::luaModalWindowGetChoiceCount(lua_State* L)
  5641. {
  5642. // modalWindow:getChoiceCount()
  5643. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5644. if (window) {
  5645. lua_pushnumber(L, window->choices.size());
  5646. } else {
  5647. lua_pushnil(L);
  5648. }
  5649. return 1;
  5650. }
  5651.  
  5652. int LuaScriptInterface::luaModalWindowAddButton(lua_State* L)
  5653. {
  5654. // modalWindow:addButton(id, text)
  5655. const std::string& text = getString(L, 3);
  5656. uint8_t id = getNumber<uint8_t>(L, 2);
  5657. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5658. if (window) {
  5659. window->buttons.emplace_back(text, id);
  5660. pushBoolean(L, true);
  5661. } else {
  5662. lua_pushnil(L);
  5663. }
  5664. return 1;
  5665. }
  5666.  
  5667. int LuaScriptInterface::luaModalWindowAddChoice(lua_State* L)
  5668. {
  5669. // modalWindow:addChoice(id, text)
  5670. const std::string& text = getString(L, 3);
  5671. uint8_t id = getNumber<uint8_t>(L, 2);
  5672. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5673. if (window) {
  5674. window->choices.emplace_back(text, id);
  5675. pushBoolean(L, true);
  5676. } else {
  5677. lua_pushnil(L);
  5678. }
  5679. return 1;
  5680. }
  5681.  
  5682. int LuaScriptInterface::luaModalWindowGetDefaultEnterButton(lua_State* L)
  5683. {
  5684. // modalWindow:getDefaultEnterButton()
  5685. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5686. if (window) {
  5687. lua_pushnumber(L, window->defaultEnterButton);
  5688. } else {
  5689. lua_pushnil(L);
  5690. }
  5691. return 1;
  5692. }
  5693.  
  5694. int LuaScriptInterface::luaModalWindowSetDefaultEnterButton(lua_State* L)
  5695. {
  5696. // modalWindow:setDefaultEnterButton(buttonId)
  5697. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5698. if (window) {
  5699. window->defaultEnterButton = getNumber<uint8_t>(L, 2);
  5700. pushBoolean(L, true);
  5701. } else {
  5702. lua_pushnil(L);
  5703. }
  5704. return 1;
  5705. }
  5706.  
  5707. int LuaScriptInterface::luaModalWindowGetDefaultEscapeButton(lua_State* L)
  5708. {
  5709. // modalWindow:getDefaultEscapeButton()
  5710. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5711. if (window) {
  5712. lua_pushnumber(L, window->defaultEscapeButton);
  5713. } else {
  5714. lua_pushnil(L);
  5715. }
  5716. return 1;
  5717. }
  5718.  
  5719. int LuaScriptInterface::luaModalWindowSetDefaultEscapeButton(lua_State* L)
  5720. {
  5721. // modalWindow:setDefaultEscapeButton(buttonId)
  5722. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5723. if (window) {
  5724. window->defaultEscapeButton = getNumber<uint8_t>(L, 2);
  5725. pushBoolean(L, true);
  5726. } else {
  5727. lua_pushnil(L);
  5728. }
  5729. return 1;
  5730. }
  5731.  
  5732. int LuaScriptInterface::luaModalWindowHasPriority(lua_State* L)
  5733. {
  5734. // modalWindow:hasPriority()
  5735. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5736. if (window) {
  5737. pushBoolean(L, window->priority);
  5738. } else {
  5739. lua_pushnil(L);
  5740. }
  5741. return 1;
  5742. }
  5743.  
  5744. int LuaScriptInterface::luaModalWindowSetPriority(lua_State* L)
  5745. {
  5746. // modalWindow:setPriority(priority)
  5747. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5748. if (window) {
  5749. window->priority = getBoolean(L, 2);
  5750. pushBoolean(L, true);
  5751. } else {
  5752. lua_pushnil(L);
  5753. }
  5754. return 1;
  5755. }
  5756.  
  5757. int LuaScriptInterface::luaModalWindowSendToPlayer(lua_State* L)
  5758. {
  5759. // modalWindow:sendToPlayer(player)
  5760. Player* player = getPlayer(L, 2);
  5761. if (!player) {
  5762. lua_pushnil(L);
  5763. return 1;
  5764. }
  5765.  
  5766. ModalWindow* window = getUserdata<ModalWindow>(L, 1);
  5767. if (window) {
  5768. if (!player->hasModalWindowOpen(window->id)) {
  5769. player->sendModalWindow(*window);
  5770. }
  5771. pushBoolean(L, true);
  5772. } else {
  5773. lua_pushnil(L);
  5774. }
  5775. return 1;
  5776. }
  5777.  
  5778. // Item
  5779. int LuaScriptInterface::luaItemCreate(lua_State* L)
  5780. {
  5781. // Item(uid)
  5782. uint32_t id = getNumber<uint32_t>(L, 2);
  5783.  
  5784. Item* item = getScriptEnv()->getItemByUID(id);
  5785. if (item) {
  5786. pushUserdata<Item>(L, item);
  5787. setItemMetatable(L, -1, item);
  5788. } else {
  5789. lua_pushnil(L);
  5790. }
  5791. return 1;
  5792. }
  5793.  
  5794. int LuaScriptInterface::luaItemIsItem(lua_State* L)
  5795. {
  5796. // item:isItem()
  5797. pushBoolean(L, getUserdata<const Item>(L, 1) != nullptr);
  5798. return 1;
  5799. }
  5800.  
  5801. int LuaScriptInterface::luaItemGetParent(lua_State* L)
  5802. {
  5803. // item:getParent()
  5804. Item* item = getUserdata<Item>(L, 1);
  5805. if (!item) {
  5806. lua_pushnil(L);
  5807. return 1;
  5808. }
  5809.  
  5810. Cylinder* parent = item->getParent();
  5811. if (!parent) {
  5812. lua_pushnil(L);
  5813. return 1;
  5814. }
  5815.  
  5816. pushCylinder(L, parent);
  5817. return 1;
  5818. }
  5819.  
  5820. int LuaScriptInterface::luaItemGetTopParent(lua_State* L)
  5821. {
  5822. // item:getTopParent()
  5823. Item* item = getUserdata<Item>(L, 1);
  5824. if (!item) {
  5825. lua_pushnil(L);
  5826. return 1;
  5827. }
  5828.  
  5829. Cylinder* topParent = item->getTopParent();
  5830. if (!topParent) {
  5831. lua_pushnil(L);
  5832. return 1;
  5833. }
  5834.  
  5835. pushCylinder(L, topParent);
  5836. return 1;
  5837. }
  5838.  
  5839. int LuaScriptInterface::luaItemGetId(lua_State* L)
  5840. {
  5841. // item:getId()
  5842. Item* item = getUserdata<Item>(L, 1);
  5843. if (item) {
  5844. lua_pushnumber(L, item->getID());
  5845. } else {
  5846. lua_pushnil(L);
  5847. }
  5848. return 1;
  5849. }
  5850.  
  5851. int LuaScriptInterface::luaItemClone(lua_State* L)
  5852. {
  5853. // item:clone()
  5854. Item* item = getUserdata<Item>(L, 1);
  5855. if (!item) {
  5856. lua_pushnil(L);
  5857. return 1;
  5858. }
  5859.  
  5860. Item* clone = item->clone();
  5861. if (!clone) {
  5862. lua_pushnil(L);
  5863. return 1;
  5864. }
  5865.  
  5866. getScriptEnv()->addTempItem(clone);
  5867. clone->setParent(VirtualCylinder::virtualCylinder);
  5868.  
  5869. pushUserdata<Item>(L, clone);
  5870. setItemMetatable(L, -1, clone);
  5871. return 1;
  5872. }
  5873.  
  5874. int LuaScriptInterface::luaItemSplit(lua_State* L)
  5875. {
  5876. // item:split([count = 1])
  5877. Item** itemPtr = getRawUserdata<Item>(L, 1);
  5878. if (!itemPtr) {
  5879. lua_pushnil(L);
  5880. return 1;
  5881. }
  5882.  
  5883. Item* item = *itemPtr;
  5884. if (!item || !item->isStackable()) {
  5885. lua_pushnil(L);
  5886. return 1;
  5887. }
  5888.  
  5889. uint16_t count = std::min<uint16_t>(getNumber<uint16_t>(L, 2, 1), item->getItemCount());
  5890. uint16_t diff = item->getItemCount() - count;
  5891.  
  5892. Item* splitItem = item->clone();
  5893. if (!splitItem) {
  5894. lua_pushnil(L);
  5895. return 1;
  5896. }
  5897.  
  5898. ScriptEnvironment* env = getScriptEnv();
  5899. uint32_t uid = env->addThing(item);
  5900.  
  5901. Item* newItem = g_game.transformItem(item, item->getID(), diff);
  5902. if (item->isRemoved()) {
  5903. env->removeItemByUID(uid);
  5904. }
  5905.  
  5906. if (newItem && newItem != item) {
  5907. env->insertItem(uid, newItem);
  5908. }
  5909.  
  5910. *itemPtr = newItem;
  5911.  
  5912. splitItem->setParent(VirtualCylinder::virtualCylinder);
  5913. env->addTempItem(splitItem);
  5914.  
  5915. pushUserdata<Item>(L, splitItem);
  5916. setItemMetatable(L, -1, splitItem);
  5917. return 1;
  5918. }
  5919.  
  5920. int LuaScriptInterface::luaItemRemove(lua_State* L)
  5921. {
  5922. // item:remove([count = -1])
  5923. Item* item = getUserdata<Item>(L, 1);
  5924. if (item) {
  5925. int32_t count = getNumber<int32_t>(L, 2, -1);
  5926. pushBoolean(L, g_game.internalRemoveItem(item, count) == RETURNVALUE_NOERROR);
  5927. } else {
  5928. lua_pushnil(L);
  5929. }
  5930. return 1;
  5931. }
  5932.  
  5933. int LuaScriptInterface::luaItemGetUniqueId(lua_State* L)
  5934. {
  5935. // item:getUniqueId()
  5936. Item* item = getUserdata<Item>(L, 1);
  5937. if (item) {
  5938. uint32_t uniqueId = item->getUniqueId();
  5939. if (uniqueId == 0) {
  5940. uniqueId = getScriptEnv()->addThing(item);
  5941. }
  5942. lua_pushnumber(L, uniqueId);
  5943. } else {
  5944. lua_pushnil(L);
  5945. }
  5946. return 1;
  5947. }
  5948.  
  5949. int LuaScriptInterface::luaItemGetActionId(lua_State* L)
  5950. {
  5951. // item:getActionId()
  5952. Item* item = getUserdata<Item>(L, 1);
  5953. if (item) {
  5954. lua_pushnumber(L, item->getActionId());
  5955. } else {
  5956. lua_pushnil(L);
  5957. }
  5958. return 1;
  5959. }
  5960.  
  5961. int LuaScriptInterface::luaItemSetActionId(lua_State* L)
  5962. {
  5963. // item:setActionId(actionId)
  5964. uint16_t actionId = getNumber<uint16_t>(L, 2);
  5965. Item* item = getUserdata<Item>(L, 1);
  5966. if (item) {
  5967. item->setActionId(actionId);
  5968. pushBoolean(L, true);
  5969. } else {
  5970. lua_pushnil(L);
  5971. }
  5972. return 1;
  5973. }
  5974.  
  5975. int LuaScriptInterface::luaItemGetCount(lua_State* L)
  5976. {
  5977. // item:getCount()
  5978. Item* item = getUserdata<Item>(L, 1);
  5979. if (item) {
  5980. lua_pushnumber(L, item->getItemCount());
  5981. } else {
  5982. lua_pushnil(L);
  5983. }
  5984. return 1;
  5985. }
  5986.  
  5987. int LuaScriptInterface::luaItemGetCharges(lua_State* L)
  5988. {
  5989. // item:getCharges()
  5990. Item* item = getUserdata<Item>(L, 1);
  5991. if (item) {
  5992. lua_pushnumber(L, item->getCharges());
  5993. } else {
  5994. lua_pushnil(L);
  5995. }
  5996. return 1;
  5997. }
  5998.  
  5999. int LuaScriptInterface::luaItemGetFluidType(lua_State* L)
  6000. {
  6001. // item:getFluidType()
  6002. Item* item = getUserdata<Item>(L, 1);
  6003. if (item) {
  6004. lua_pushnumber(L, item->getFluidType());
  6005. } else {
  6006. lua_pushnil(L);
  6007. }
  6008. return 1;
  6009. }
  6010.  
  6011. int LuaScriptInterface::luaItemGetWeight(lua_State* L)
  6012. {
  6013. // item:getWeight()
  6014. Item* item = getUserdata<Item>(L, 1);
  6015. if (item) {
  6016. lua_pushnumber(L, item->getWeight());
  6017. } else {
  6018. lua_pushnil(L);
  6019. }
  6020. return 1;
  6021. }
  6022.  
  6023. int LuaScriptInterface::luaItemGetSubType(lua_State* L)
  6024. {
  6025. // item:getSubType()
  6026. Item* item = getUserdata<Item>(L, 1);
  6027. if (item) {
  6028. lua_pushnumber(L, item->getSubType());
  6029. } else {
  6030. lua_pushnil(L);
  6031. }
  6032. return 1;
  6033. }
  6034.  
  6035. int LuaScriptInterface::luaItemGetName(lua_State* L)
  6036. {
  6037. // item:getName()
  6038. Item* item = getUserdata<Item>(L, 1);
  6039. if (item) {
  6040. pushString(L, item->getName());
  6041. } else {
  6042. lua_pushnil(L);
  6043. }
  6044. return 1;
  6045. }
  6046.  
  6047. int LuaScriptInterface::luaItemGetPluralName(lua_State* L)
  6048. {
  6049. // item:getPluralName()
  6050. Item* item = getUserdata<Item>(L, 1);
  6051. if (item) {
  6052. pushString(L, item->getPluralName());
  6053. } else {
  6054. lua_pushnil(L);
  6055. }
  6056. return 1;
  6057. }
  6058.  
  6059. int LuaScriptInterface::luaItemGetArticle(lua_State* L)
  6060. {
  6061. // item:getArticle()
  6062. Item* item = getUserdata<Item>(L, 1);
  6063. if (item) {
  6064. pushString(L, item->getArticle());
  6065. } else {
  6066. lua_pushnil(L);
  6067. }
  6068. return 1;
  6069. }
  6070.  
  6071. int LuaScriptInterface::luaItemGetPosition(lua_State* L)
  6072. {
  6073. // item:getPosition()
  6074. Item* item = getUserdata<Item>(L, 1);
  6075. if (item) {
  6076. pushPosition(L, item->getPosition());
  6077. } else {
  6078. lua_pushnil(L);
  6079. }
  6080. return 1;
  6081. }
  6082.  
  6083. int LuaScriptInterface::luaItemGetTile(lua_State* L)
  6084. {
  6085. // item:getTile()
  6086. Item* item = getUserdata<Item>(L, 1);
  6087. if (!item) {
  6088. lua_pushnil(L);
  6089. return 1;
  6090. }
  6091.  
  6092. Tile* tile = item->getTile();
  6093. if (tile) {
  6094. pushUserdata<Tile>(L, tile);
  6095. setMetatable(L, -1, "Tile");
  6096. } else {
  6097. lua_pushnil(L);
  6098. }
  6099. return 1;
  6100. }
  6101.  
  6102. int LuaScriptInterface::luaItemHasAttribute(lua_State* L)
  6103. {
  6104. // item:hasAttribute(key)
  6105. Item* item = getUserdata<Item>(L, 1);
  6106. if (!item) {
  6107. lua_pushnil(L);
  6108. return 1;
  6109. }
  6110.  
  6111. itemAttrTypes attribute;
  6112. if (isNumber(L, 2)) {
  6113. attribute = getNumber<itemAttrTypes>(L, 2);
  6114. } else if (isString(L, 2)) {
  6115. attribute = stringToItemAttribute(getString(L, 2));
  6116. } else {
  6117. attribute = ITEM_ATTRIBUTE_NONE;
  6118. }
  6119.  
  6120. pushBoolean(L, item->hasAttribute(attribute));
  6121. return 1;
  6122. }
  6123.  
  6124. int LuaScriptInterface::luaItemGetAttribute(lua_State* L)
  6125. {
  6126. // item:getAttribute(key)
  6127. Item* item = getUserdata<Item>(L, 1);
  6128. if (!item) {
  6129. lua_pushnil(L);
  6130. return 1;
  6131. }
  6132.  
  6133. itemAttrTypes attribute;
  6134. if (isNumber(L, 2)) {
  6135. attribute = getNumber<itemAttrTypes>(L, 2);
  6136. } else if (isString(L, 2)) {
  6137. attribute = stringToItemAttribute(getString(L, 2));
  6138. } else {
  6139. attribute = ITEM_ATTRIBUTE_NONE;
  6140. }
  6141.  
  6142. if (ItemAttributes::isIntAttrType(attribute)) {
  6143. lua_pushnumber(L, item->getIntAttr(attribute));
  6144. } else if (ItemAttributes::isStrAttrType(attribute)) {
  6145. pushString(L, item->getStrAttr(attribute));
  6146. } else {
  6147. lua_pushnil(L);
  6148. }
  6149. return 1;
  6150. }
  6151.  
  6152. int LuaScriptInterface::luaItemSetAttribute(lua_State* L)
  6153. {
  6154. // item:setAttribute(key, value)
  6155. Item* item = getUserdata<Item>(L, 1);
  6156. if (!item) {
  6157. lua_pushnil(L);
  6158. return 1;
  6159. }
  6160.  
  6161. itemAttrTypes attribute;
  6162. if (isNumber(L, 2)) {
  6163. attribute = getNumber<itemAttrTypes>(L, 2);
  6164. } else if (isString(L, 2)) {
  6165. attribute = stringToItemAttribute(getString(L, 2));
  6166. } else {
  6167. attribute = ITEM_ATTRIBUTE_NONE;
  6168. }
  6169.  
  6170. if (ItemAttributes::isIntAttrType(attribute)) {
  6171. if (attribute == ITEM_ATTRIBUTE_UNIQUEID) {
  6172. reportErrorFunc("Attempt to set protected key \"uid\"");
  6173. pushBoolean(L, false);
  6174. return 1;
  6175. }
  6176.  
  6177. item->setIntAttr(attribute, getNumber<int32_t>(L, 3));
  6178. pushBoolean(L, true);
  6179. } else if (ItemAttributes::isStrAttrType(attribute)) {
  6180. item->setStrAttr(attribute, getString(L, 3));
  6181. pushBoolean(L, true);
  6182. } else {
  6183. lua_pushnil(L);
  6184. }
  6185. return 1;
  6186. }
  6187.  
  6188. int LuaScriptInterface::luaItemRemoveAttribute(lua_State* L)
  6189. {
  6190. // item:removeAttribute(key)
  6191. Item* item = getUserdata<Item>(L, 1);
  6192. if (!item) {
  6193. lua_pushnil(L);
  6194. return 1;
  6195. }
  6196.  
  6197. itemAttrTypes attribute;
  6198. if (isNumber(L, 2)) {
  6199. attribute = getNumber<itemAttrTypes>(L, 2);
  6200. } else if (isString(L, 2)) {
  6201. attribute = stringToItemAttribute(getString(L, 2));
  6202. } else {
  6203. attribute = ITEM_ATTRIBUTE_NONE;
  6204. }
  6205.  
  6206. bool ret = attribute != ITEM_ATTRIBUTE_UNIQUEID;
  6207. if (ret) {
  6208. item->removeAttribute(attribute);
  6209. } else {
  6210. reportErrorFunc("Attempt to erase protected key \"uid\"");
  6211. }
  6212. pushBoolean(L, ret);
  6213. return 1;
  6214. }
  6215.  
  6216. int LuaScriptInterface::luaItemSerializeAttributes(lua_State* L)
  6217. {
  6218. // item:serializeAttributes()
  6219. Item* item = getUserdata<Item>(L, 1);
  6220. if (!item) {
  6221. lua_pushnil(L);
  6222. return 1;
  6223. }
  6224.  
  6225. PropWriteStream propWriteStream;
  6226. item->serializeAttr(propWriteStream);
  6227.  
  6228. size_t attributesSize;
  6229. const char* attributes = propWriteStream.getStream(attributesSize);
  6230. lua_pushlstring(L, attributes, attributesSize);
  6231. return 1;
  6232. }
  6233.  
  6234. int LuaScriptInterface::luaItemMoveTo(lua_State* L)
  6235. {
  6236. // item:moveTo(position or cylinder)
  6237. Item** itemPtr = getRawUserdata<Item>(L, 1);
  6238. if (!itemPtr) {
  6239. lua_pushnil(L);
  6240. return 1;
  6241. }
  6242.  
  6243. Item* item = *itemPtr;
  6244. if (!item || item->isRemoved()) {
  6245. lua_pushnil(L);
  6246. return 1;
  6247. }
  6248.  
  6249. Cylinder* toCylinder;
  6250. if (isUserdata(L, 2)) {
  6251. const LuaDataType type = getUserdataType(L, 2);
  6252. switch (type) {
  6253. case LuaData_Container:
  6254. toCylinder = getUserdata<Container>(L, 2);
  6255. break;
  6256. case LuaData_Player:
  6257. toCylinder = getUserdata<Player>(L, 2);
  6258. break;
  6259. case LuaData_Tile:
  6260. toCylinder = getUserdata<Tile>(L, 2);
  6261. break;
  6262. default:
  6263. toCylinder = nullptr;
  6264. break;
  6265. }
  6266. } else {
  6267. toCylinder = g_game.map.getTile(getPosition(L, 2));
  6268. }
  6269.  
  6270. if (!toCylinder) {
  6271. lua_pushnil(L);
  6272. return 1;
  6273. }
  6274.  
  6275. if (item->getParent() == toCylinder) {
  6276. pushBoolean(L, true);
  6277. return 1;
  6278. }
  6279.  
  6280. if (item->getParent() == VirtualCylinder::virtualCylinder) {
  6281. pushBoolean(L, g_game.internalAddItem(toCylinder, item) == RETURNVALUE_NOERROR);
  6282. } else {
  6283. Item* moveItem = nullptr;
  6284. ReturnValue ret = g_game.internalMoveItem(item->getParent(), toCylinder, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem, FLAG_NOLIMIT | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE | FLAG_IGNORENOTMOVEABLE);
  6285. if (moveItem) {
  6286. *itemPtr = moveItem;
  6287. }
  6288. pushBoolean(L, ret == RETURNVALUE_NOERROR);
  6289. }
  6290. return 1;
  6291. }
  6292.  
  6293. int LuaScriptInterface::luaItemTransform(lua_State* L)
  6294. {
  6295. // item:transform(itemId[, count/subType = -1])
  6296. Item** itemPtr = getRawUserdata<Item>(L, 1);
  6297. if (!itemPtr) {
  6298. lua_pushnil(L);
  6299. return 1;
  6300. }
  6301.  
  6302. Item*& item = *itemPtr;
  6303. if (!item) {
  6304. lua_pushnil(L);
  6305. return 1;
  6306. }
  6307.  
  6308. uint16_t itemId;
  6309. if (isNumber(L, 2)) {
  6310. itemId = getNumber<uint16_t>(L, 2);
  6311. } else {
  6312. itemId = Item::items.getItemIdByName(getString(L, 2));
  6313. if (itemId == 0) {
  6314. lua_pushnil(L);
  6315. return 1;
  6316. }
  6317. }
  6318.  
  6319. int32_t subType = getNumber<int32_t>(L, 3, -1);
  6320. if (item->getID() == itemId && (subType == -1 || subType == item->getSubType())) {
  6321. pushBoolean(L, true);
  6322. return 1;
  6323. }
  6324.  
  6325. const ItemType& it = Item::items[itemId];
  6326. if (it.stackable) {
  6327. subType = std::min<int32_t>(subType, 100);
  6328. }
  6329.  
  6330. ScriptEnvironment* env = getScriptEnv();
  6331. uint32_t uid = env->addThing(item);
  6332.  
  6333. Item* newItem = g_game.transformItem(item, itemId, subType);
  6334. if (item->isRemoved()) {
  6335. env->removeItemByUID(uid);
  6336. }
  6337.  
  6338. if (newItem && newItem != item) {
  6339. env->insertItem(uid, newItem);
  6340. }
  6341.  
  6342. item = newItem;
  6343. pushBoolean(L, true);
  6344. return 1;
  6345. }
  6346.  
  6347. int LuaScriptInterface::luaItemDecay(lua_State* L)
  6348. {
  6349. // item:decay()
  6350. Item* item = getUserdata<Item>(L, 1);
  6351. if (item) {
  6352. g_game.startDecay(item);
  6353. pushBoolean(L, true);
  6354. } else {
  6355. lua_pushnil(L);
  6356. }
  6357. return 1;
  6358. }
  6359.  
  6360. int LuaScriptInterface::luaItemGetDescription(lua_State* L)
  6361. {
  6362. // item:getDescription(distance)
  6363. Item* item = getUserdata<Item>(L, 1);
  6364. if (item) {
  6365. int32_t distance = getNumber<int32_t>(L, 2);
  6366. pushString(L, item->getDescription(distance));
  6367. } else {
  6368. lua_pushnil(L);
  6369. }
  6370. return 1;
  6371. }
  6372.  
  6373. int LuaScriptInterface::luaItemHasProperty(lua_State* L)
  6374. {
  6375. // item:hasProperty(property)
  6376. Item* item = getUserdata<Item>(L, 1);
  6377. if (item) {
  6378. ITEMPROPERTY property = getNumber<ITEMPROPERTY>(L, 2);
  6379. pushBoolean(L, item->hasProperty(property));
  6380. } else {
  6381. lua_pushnil(L);
  6382. }
  6383. return 1;
  6384. }
  6385.  
  6386. // Container
  6387. int LuaScriptInterface::luaContainerCreate(lua_State* L)
  6388. {
  6389. // Container(uid)
  6390. uint32_t id = getNumber<uint32_t>(L, 2);
  6391.  
  6392. Container* container = getScriptEnv()->getContainerByUID(id);
  6393. if (container) {
  6394. pushUserdata(L, container);
  6395. setMetatable(L, -1, "Container");
  6396. } else {
  6397. lua_pushnil(L);
  6398. }
  6399. return 1;
  6400. }
  6401.  
  6402. int LuaScriptInterface::luaContainerGetSize(lua_State* L)
  6403. {
  6404. // container:getSize()
  6405. Container* container = getUserdata<Container>(L, 1);
  6406. if (container) {
  6407. lua_pushnumber(L, container->size());
  6408. } else {
  6409. lua_pushnil(L);
  6410. }
  6411. return 1;
  6412. }
  6413.  
  6414. int LuaScriptInterface::luaContainerGetCapacity(lua_State* L)
  6415. {
  6416. // container:getCapacity()
  6417. Container* container = getUserdata<Container>(L, 1);
  6418. if (container) {
  6419. lua_pushnumber(L, container->capacity());
  6420. } else {
  6421. lua_pushnil(L);
  6422. }
  6423. return 1;
  6424. }
  6425.  
  6426. int LuaScriptInterface::luaContainerGetEmptySlots(lua_State* L)
  6427. {
  6428. // container:getEmptySlots([recursive = false])
  6429. Container* container = getUserdata<Container>(L, 1);
  6430. if (!container) {
  6431. lua_pushnil(L);
  6432. return 1;
  6433. }
  6434.  
  6435. uint32_t slots = container->capacity() - container->size();
  6436. bool recursive = getBoolean(L, 2, false);
  6437. if (recursive) {
  6438. for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
  6439. if (Container* tmpContainer = (*it)->getContainer()) {
  6440. slots += tmpContainer->capacity() - tmpContainer->size();
  6441. }
  6442. }
  6443. }
  6444. lua_pushnumber(L, slots);
  6445. return 1;
  6446. }
  6447.  
  6448. int LuaScriptInterface::luaContainerGetItemHoldingCount(lua_State* L)
  6449. {
  6450. // container:getItemHoldingCount()
  6451. Container* container = getUserdata<Container>(L, 1);
  6452. if (container) {
  6453. lua_pushnumber(L, container->getItemHoldingCount());
  6454. } else {
  6455. lua_pushnil(L);
  6456. }
  6457. return 1;
  6458. }
  6459.  
  6460. int LuaScriptInterface::luaContainerGetItem(lua_State* L)
  6461. {
  6462. // container:getItem(index)
  6463. Container* container = getUserdata<Container>(L, 1);
  6464. if (!container) {
  6465. lua_pushnil(L);
  6466. return 1;
  6467. }
  6468.  
  6469. uint32_t index = getNumber<uint32_t>(L, 2);
  6470. Item* item = container->getItemByIndex(index);
  6471. if (item) {
  6472. pushUserdata<Item>(L, item);
  6473. setItemMetatable(L, -1, item);
  6474. } else {
  6475. lua_pushnil(L);
  6476. }
  6477. return 1;
  6478. }
  6479.  
  6480. int LuaScriptInterface::luaContainerHasItem(lua_State* L)
  6481. {
  6482. // container:hasItem(item)
  6483. Item* item = getUserdata<Item>(L, 2);
  6484. Container* container = getUserdata<Container>(L, 1);
  6485. if (container) {
  6486. pushBoolean(L, container->isHoldingItem(item));
  6487. } else {
  6488. lua_pushnil(L);
  6489. }
  6490. return 1;
  6491. }
  6492.  
  6493. int LuaScriptInterface::luaContainerAddItem(lua_State* L)
  6494. {
  6495. // container:addItem(itemId[, count/subType = 1[, index = INDEX_WHEREEVER[, flags = 0]]])
  6496. Container* container = getUserdata<Container>(L, 1);
  6497. if (!container) {
  6498. lua_pushnil(L);
  6499. return 1;
  6500. }
  6501.  
  6502. uint16_t itemId;
  6503. if (isNumber(L, 2)) {
  6504. itemId = getNumber<uint16_t>(L, 2);
  6505. } else {
  6506. itemId = Item::items.getItemIdByName(getString(L, 2));
  6507. if (itemId == 0) {
  6508. lua_pushnil(L);
  6509. return 1;
  6510. }
  6511. }
  6512.  
  6513. uint32_t subType = getNumber<uint32_t>(L, 3, 1);
  6514.  
  6515. Item* item = Item::CreateItem(itemId, std::min<uint32_t>(subType, 100));
  6516. if (!item) {
  6517. lua_pushnil(L);
  6518. return 1;
  6519. }
  6520.  
  6521. int32_t index = getNumber<int32_t>(L, 4, INDEX_WHEREEVER);
  6522. uint32_t flags = getNumber<uint32_t>(L, 5, 0);
  6523.  
  6524. ReturnValue ret = g_game.internalAddItem(container, item, index, flags);
  6525. if (ret == RETURNVALUE_NOERROR) {
  6526. pushUserdata<Item>(L, item);
  6527. setItemMetatable(L, -1, item);
  6528. } else {
  6529. delete item;
  6530. lua_pushnil(L);
  6531. }
  6532. return 1;
  6533. }
  6534.  
  6535. int LuaScriptInterface::luaContainerAddItemEx(lua_State* L)
  6536. {
  6537. // container:addItemEx(item[, index = INDEX_WHEREEVER[, flags = 0]])
  6538. Item* item = getUserdata<Item>(L, 2);
  6539. if (!item) {
  6540. lua_pushnil(L);
  6541. return 1;
  6542. }
  6543.  
  6544. Container* container = getUserdata<Container>(L, 1);
  6545. if (!container) {
  6546. lua_pushnil(L);
  6547. return 1;
  6548. }
  6549.  
  6550. if (item->getParent() != VirtualCylinder::virtualCylinder) {
  6551. reportErrorFunc("Item already has a parent");
  6552. lua_pushnil(L);
  6553. return 1;
  6554. }
  6555.  
  6556. int32_t index = getNumber<int32_t>(L, 3, INDEX_WHEREEVER);
  6557. uint32_t flags = getNumber<uint32_t>(L, 4, 0);
  6558. ReturnValue ret = g_game.internalAddItem(container, item, index, flags);
  6559. if (ret == RETURNVALUE_NOERROR) {
  6560. ScriptEnvironment::removeTempItem(item);
  6561. }
  6562. lua_pushnumber(L, ret);
  6563. return 1;
  6564. }
  6565.  
  6566. int LuaScriptInterface::luaContainerGetItemCountById(lua_State* L)
  6567. {
  6568. // container:getItemCountById(itemId[, subType = -1])
  6569. Container* container = getUserdata<Container>(L, 1);
  6570. if (!container) {
  6571. lua_pushnil(L);
  6572. return 1;
  6573. }
  6574.  
  6575. uint16_t itemId;
  6576. if (isNumber(L, 2)) {
  6577. itemId = getNumber<uint16_t>(L, 2);
  6578. } else {
  6579. itemId = Item::items.getItemIdByName(getString(L, 2));
  6580. if (itemId == 0) {
  6581. lua_pushnil(L);
  6582. return 1;
  6583. }
  6584. }
  6585.  
  6586. int32_t subType = getNumber<int32_t>(L, 3, -1);
  6587. lua_pushnumber(L, container->getItemTypeCount(itemId, subType));
  6588. return 1;
  6589. }
  6590.  
  6591. // Teleport
  6592. int LuaScriptInterface::luaTeleportCreate(lua_State* L)
  6593. {
  6594. // Teleport(uid)
  6595. uint32_t id = getNumber<uint32_t>(L, 2);
  6596.  
  6597. Item* item = getScriptEnv()->getItemByUID(id);
  6598. if (item && item->getTeleport()) {
  6599. pushUserdata(L, item);
  6600. setMetatable(L, -1, "Teleport");
  6601. } else {
  6602. lua_pushnil(L);
  6603. }
  6604. return 1;
  6605. }
  6606.  
  6607. int LuaScriptInterface::luaTeleportGetDestination(lua_State* L)
  6608. {
  6609. // teleport:getDestination()
  6610. Teleport* teleport = getUserdata<Teleport>(L, 1);
  6611. if (teleport) {
  6612. pushPosition(L, teleport->getDestPos());
  6613. } else {
  6614. lua_pushnil(L);
  6615. }
  6616. return 1;
  6617. }
  6618.  
  6619. int LuaScriptInterface::luaTeleportSetDestination(lua_State* L)
  6620. {
  6621. // teleport:setDestination(position)
  6622. Teleport* teleport = getUserdata<Teleport>(L, 1);
  6623. if (teleport) {
  6624. teleport->setDestPos(getPosition(L, 2));
  6625. pushBoolean(L, true);
  6626. } else {
  6627. lua_pushnil(L);
  6628. }
  6629. return 1;
  6630. }
  6631.  
  6632. // Creature
  6633. int LuaScriptInterface::luaCreatureCreate(lua_State* L)
  6634. {
  6635. // Creature(id or name or userdata)
  6636. Creature* creature;
  6637. if (isNumber(L, 2)) {
  6638. creature = g_game.getCreatureByID(getNumber<uint32_t>(L, 2));
  6639. } else if (isString(L, 2)) {
  6640. creature = g_game.getCreatureByName(getString(L, 2));
  6641. } else if (isUserdata(L, 2)) {
  6642. LuaDataType type = getUserdataType(L, 2);
  6643. if (type != LuaData_Player && type != LuaData_Monster && type != LuaData_Npc) {
  6644. lua_pushnil(L);
  6645. return 1;
  6646. }
  6647. creature = getUserdata<Creature>(L, 2);
  6648. } else {
  6649. creature = nullptr;
  6650. }
  6651.  
  6652. if (creature) {
  6653. pushUserdata<Creature>(L, creature);
  6654. setCreatureMetatable(L, -1, creature);
  6655. } else {
  6656. lua_pushnil(L);
  6657. }
  6658. return 1;
  6659. }
  6660.  
  6661. int LuaScriptInterface::luaCreatureRegisterEvent(lua_State* L)
  6662. {
  6663. // creature:registerEvent(name)
  6664. Creature* creature = getUserdata<Creature>(L, 1);
  6665. if (creature) {
  6666. const std::string& name = getString(L, 2);
  6667. pushBoolean(L, creature->registerCreatureEvent(name));
  6668. } else {
  6669. lua_pushnil(L);
  6670. }
  6671. return 1;
  6672. }
  6673.  
  6674. int LuaScriptInterface::luaCreatureUnregisterEvent(lua_State* L)
  6675. {
  6676. // creature:unregisterEvent(name)
  6677. const std::string& name = getString(L, 2);
  6678. Creature* creature = getUserdata<Creature>(L, 1);
  6679. if (creature) {
  6680. pushBoolean(L, creature->unregisterCreatureEvent(name));
  6681. } else {
  6682. lua_pushnil(L);
  6683. }
  6684. return 1;
  6685. }
  6686.  
  6687. int LuaScriptInterface::luaCreatureIsRemoved(lua_State* L)
  6688. {
  6689. // creature:isRemoved()
  6690. const Creature* creature = getUserdata<const Creature>(L, 1);
  6691. if (creature) {
  6692. pushBoolean(L, creature->isRemoved());
  6693. } else {
  6694. lua_pushnil(L);
  6695. }
  6696. return 1;
  6697. }
  6698.  
  6699. int LuaScriptInterface::luaCreatureIsCreature(lua_State* L)
  6700. {
  6701. // creature:isCreature()
  6702. pushBoolean(L, getUserdata<const Creature>(L, 1) != nullptr);
  6703. return 1;
  6704. }
  6705.  
  6706. int LuaScriptInterface::luaCreatureIsInGhostMode(lua_State* L)
  6707. {
  6708. // creature:isInGhostMode()
  6709. const Creature* creature = getUserdata<const Creature>(L, 1);
  6710. if (creature) {
  6711. pushBoolean(L, creature->isInGhostMode());
  6712. } else {
  6713. lua_pushnil(L);
  6714. }
  6715. return 1;
  6716. }
  6717.  
  6718. int LuaScriptInterface::luaCreatureIsHealthHidden(lua_State* L)
  6719. {
  6720. // creature:isHealthHidden()
  6721. const Creature* creature = getUserdata<const Creature>(L, 1);
  6722. if (creature) {
  6723. pushBoolean(L, creature->isHealthHidden());
  6724. } else {
  6725. lua_pushnil(L);
  6726. }
  6727. return 1;
  6728. }
  6729.  
  6730. int LuaScriptInterface::luaCreatureCanSee(lua_State* L)
  6731. {
  6732. // creature:canSee(position)
  6733. const Creature* creature = getUserdata<const Creature>(L, 1);
  6734. if (creature) {
  6735. const Position& position = getPosition(L, 2);
  6736. pushBoolean(L, creature->canSee(position));
  6737. } else {
  6738. lua_pushnil(L);
  6739. }
  6740. return 1;
  6741. }
  6742.  
  6743. int LuaScriptInterface::luaCreatureCanSeeCreature(lua_State* L)
  6744. {
  6745. // creature:canSeeCreature(creature)
  6746. const Creature* creature = getUserdata<const Creature>(L, 1);
  6747. if (creature) {
  6748. const Creature* otherCreature = getCreature(L, 2);
  6749. pushBoolean(L, creature->canSeeCreature(otherCreature));
  6750. } else {
  6751. lua_pushnil(L);
  6752. }
  6753. return 1;
  6754. }
  6755.  
  6756. int LuaScriptInterface::luaCreatureGetParent(lua_State* L)
  6757. {
  6758. // creature:getParent()
  6759. Creature* creature = getUserdata<Creature>(L, 1);
  6760. if (!creature) {
  6761. lua_pushnil(L);
  6762. return 1;
  6763. }
  6764.  
  6765. Cylinder* parent = creature->getParent();
  6766. if (!parent) {
  6767. lua_pushnil(L);
  6768. return 1;
  6769. }
  6770.  
  6771. pushCylinder(L, parent);
  6772. return 1;
  6773. }
  6774.  
  6775. int LuaScriptInterface::luaCreatureGetId(lua_State* L)
  6776. {
  6777. // creature:getId()
  6778. const Creature* creature = getUserdata<const Creature>(L, 1);
  6779. if (creature) {
  6780. lua_pushnumber(L, creature->getID());
  6781. } else {
  6782. lua_pushnil(L);
  6783. }
  6784. return 1;
  6785. }
  6786.  
  6787. int LuaScriptInterface::luaCreatureGetName(lua_State* L)
  6788. {
  6789. // creature:getName()
  6790. const Creature* creature = getUserdata<const Creature>(L, 1);
  6791. if (creature) {
  6792. pushString(L, creature->getName());
  6793. } else {
  6794. lua_pushnil(L);
  6795. }
  6796. return 1;
  6797. }
  6798.  
  6799. int LuaScriptInterface::luaCreatureGetTarget(lua_State* L)
  6800. {
  6801. // creature:getTarget()
  6802. Creature* creature = getUserdata<Creature>(L, 1);
  6803. if (!creature) {
  6804. lua_pushnil(L);
  6805. return 1;
  6806. }
  6807.  
  6808. Creature* target = creature->getAttackedCreature();
  6809. if (target) {
  6810. pushUserdata<Creature>(L, target);
  6811. setCreatureMetatable(L, -1, target);
  6812. } else {
  6813. lua_pushnil(L);
  6814. }
  6815. return 1;
  6816. }
  6817.  
  6818. int LuaScriptInterface::luaCreatureSetTarget(lua_State* L)
  6819. {
  6820. // creature:setTarget(target)
  6821. Creature* creature = getUserdata<Creature>(L, 1);
  6822. if (creature) {
  6823. Creature* target = getCreature(L, 2);
  6824. pushBoolean(L, creature->setAttackedCreature(target));
  6825. } else {
  6826. lua_pushnil(L);
  6827. }
  6828. return 1;
  6829. }
  6830.  
  6831. int LuaScriptInterface::luaCreatureGetFollowCreature(lua_State* L)
  6832. {
  6833. // creature:getFollowCreature()
  6834. Creature* creature = getUserdata<Creature>(L, 1);
  6835. if (!creature) {
  6836. lua_pushnil(L);
  6837. return 1;
  6838. }
  6839.  
  6840. Creature* followCreature = creature->getFollowCreature();
  6841. if (followCreature) {
  6842. pushUserdata<Creature>(L, followCreature);
  6843. setCreatureMetatable(L, -1, followCreature);
  6844. } else {
  6845. lua_pushnil(L);
  6846. }
  6847. return 1;
  6848. }
  6849.  
  6850. int LuaScriptInterface::luaCreatureSetFollowCreature(lua_State* L)
  6851. {
  6852. // creature:setFollowCreature(followedCreature)
  6853. Creature* creature = getUserdata<Creature>(L, 1);
  6854. if (creature) {
  6855. Creature* followCreature = getCreature(L, 2);
  6856. pushBoolean(L, creature->setFollowCreature(followCreature));
  6857. } else {
  6858. lua_pushnil(L);
  6859. }
  6860. return 1;
  6861. }
  6862.  
  6863. int LuaScriptInterface::luaCreatureGetMaster(lua_State* L)
  6864. {
  6865. // creature:getMaster()
  6866. Creature* creature = getUserdata<Creature>(L, 1);
  6867. if (!creature) {
  6868. lua_pushnil(L);
  6869. return 1;
  6870. }
  6871.  
  6872. Creature* master = creature->getMaster();
  6873. if (!master) {
  6874. lua_pushnil(L);
  6875. return 1;
  6876. }
  6877.  
  6878. pushUserdata<Creature>(L, master);
  6879. setCreatureMetatable(L, -1, master);
  6880. return 1;
  6881. }
  6882.  
  6883. int LuaScriptInterface::luaCreatureSetMaster(lua_State* L)
  6884. {
  6885. // creature:setMaster(master)
  6886. Creature* creature = getUserdata<Creature>(L, 1);
  6887. if (!creature) {
  6888. lua_pushnil(L);
  6889. return 1;
  6890. }
  6891.  
  6892. Creature* master = getCreature(L, 2);
  6893. if (master) {
  6894. pushBoolean(L, creature->convinceCreature(master));
  6895. } else {
  6896. master = creature->getMaster();
  6897. if (master) {
  6898. master->removeSummon(creature);
  6899. creature->incrementReferenceCounter();
  6900. creature->setDropLoot(true);
  6901. }
  6902. pushBoolean(L, true);
  6903. }
  6904. g_game.updateCreatureType(creature);
  6905. return 1;
  6906. }
  6907.  
  6908. int LuaScriptInterface::luaCreatureGetLight(lua_State* L)
  6909. {
  6910. // creature:getLight()
  6911. const Creature* creature = getUserdata<const Creature>(L, 1);
  6912. if (!creature) {
  6913. lua_pushnil(L);
  6914. return 1;
  6915. }
  6916.  
  6917. LightInfo light;
  6918. creature->getCreatureLight(light);
  6919. lua_pushnumber(L, light.level);
  6920. lua_pushnumber(L, light.color);
  6921. return 2;
  6922. }
  6923.  
  6924. int LuaScriptInterface::luaCreatureSetLight(lua_State* L)
  6925. {
  6926. // creature:setLight(color, level)
  6927. Creature* creature = getUserdata<Creature>(L, 1);
  6928. if (!creature) {
  6929. lua_pushnil(L);
  6930. return 1;
  6931. }
  6932.  
  6933. LightInfo light;
  6934. light.color = getNumber<uint8_t>(L, 2);
  6935. light.level = getNumber<uint8_t>(L, 3);
  6936. creature->setCreatureLight(light);
  6937. g_game.changeLight(creature);
  6938. pushBoolean(L, true);
  6939. return 1;
  6940. }
  6941.  
  6942. int LuaScriptInterface::luaCreatureGetSpeed(lua_State* L)
  6943. {
  6944. // creature:getSpeed()
  6945. const Creature* creature = getUserdata<const Creature>(L, 1);
  6946. if (creature) {
  6947. lua_pushnumber(L, creature->getSpeed());
  6948. } else {
  6949. lua_pushnil(L);
  6950. }
  6951. return 1;
  6952. }
  6953.  
  6954. int LuaScriptInterface::luaCreatureGetBaseSpeed(lua_State* L)
  6955. {
  6956. // creature:getBaseSpeed()
  6957. const Creature* creature = getUserdata<const Creature>(L, 1);
  6958. if (creature) {
  6959. lua_pushnumber(L, creature->getBaseSpeed());
  6960. } else {
  6961. lua_pushnil(L);
  6962. }
  6963. return 1;
  6964. }
  6965.  
  6966. int LuaScriptInterface::luaCreatureChangeSpeed(lua_State* L)
  6967. {
  6968. // creature:changeSpeed(delta)
  6969. Creature* creature = getCreature(L, 1);
  6970. if (!creature) {
  6971. reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  6972. pushBoolean(L, false);
  6973. return 1;
  6974. }
  6975.  
  6976. int32_t delta = getNumber<int32_t>(L, 2);
  6977. g_game.changeSpeed(creature, delta);
  6978. pushBoolean(L, true);
  6979. return 1;
  6980. }
  6981.  
  6982. int LuaScriptInterface::luaCreatureSetDropLoot(lua_State* L)
  6983. {
  6984. // creature:setDropLoot(doDrop)
  6985. Creature* creature = getUserdata<Creature>(L, 1);
  6986. if (creature) {
  6987. creature->setDropLoot(getBoolean(L, 2));
  6988. pushBoolean(L, true);
  6989. } else {
  6990. lua_pushnil(L);
  6991. }
  6992. return 1;
  6993. }
  6994.  
  6995. int LuaScriptInterface::luaCreatureGetPosition(lua_State* L)
  6996. {
  6997. // creature:getPosition()
  6998. const Creature* creature = getUserdata<const Creature>(L, 1);
  6999. if (creature) {
  7000. pushPosition(L, creature->getPosition());
  7001. } else {
  7002. lua_pushnil(L);
  7003. }
  7004. return 1;
  7005. }
  7006.  
  7007. int LuaScriptInterface::luaCreatureGetTile(lua_State* L)
  7008. {
  7009. // creature:getTile()
  7010. Creature* creature = getUserdata<Creature>(L, 1);
  7011. if (!creature) {
  7012. lua_pushnil(L);
  7013. return 1;
  7014. }
  7015.  
  7016. Tile* tile = creature->getTile();
  7017. if (tile) {
  7018. pushUserdata<Tile>(L, tile);
  7019. setMetatable(L, -1, "Tile");
  7020. } else {
  7021. lua_pushnil(L);
  7022. }
  7023. return 1;
  7024. }
  7025.  
  7026. int LuaScriptInterface::luaCreatureGetDirection(lua_State* L)
  7027. {
  7028. // creature:getDirection()
  7029. const Creature* creature = getUserdata<const Creature>(L, 1);
  7030. if (creature) {
  7031. lua_pushnumber(L, creature->getDirection());
  7032. } else {
  7033. lua_pushnil(L);
  7034. }
  7035. return 1;
  7036. }
  7037.  
  7038. int LuaScriptInterface::luaCreatureSetDirection(lua_State* L)
  7039. {
  7040. // creature:setDirection(direction)
  7041. Creature* creature = getUserdata<Creature>(L, 1);
  7042. if (creature) {
  7043. pushBoolean(L, g_game.internalCreatureTurn(creature, getNumber<Direction>(L, 2)));
  7044. } else {
  7045. lua_pushnil(L);
  7046. }
  7047. return 1;
  7048. }
  7049.  
  7050. int LuaScriptInterface::luaCreatureGetHealth(lua_State* L)
  7051. {
  7052. // creature:getHealth()
  7053. const Creature* creature = getUserdata<const Creature>(L, 1);
  7054. if (creature) {
  7055. lua_pushnumber(L, creature->getHealth());
  7056. } else {
  7057. lua_pushnil(L);
  7058. }
  7059. return 1;
  7060. }
  7061.  
  7062. int LuaScriptInterface::luaCreatureAddHealth(lua_State* L)
  7063. {
  7064. // creature:addHealth(healthChange)
  7065. Creature* creature = getUserdata<Creature>(L, 1);
  7066. if (!creature) {
  7067. lua_pushnil(L);
  7068. return 1;
  7069. }
  7070.  
  7071. CombatDamage damage;
  7072. damage.primary.value = getNumber<int32_t>(L, 2);
  7073. if (damage.primary.value >= 0) {
  7074. damage.primary.type = COMBAT_HEALING;
  7075. } else {
  7076. damage.primary.type = COMBAT_UNDEFINEDDAMAGE;
  7077. }
  7078. pushBoolean(L, g_game.combatChangeHealth(nullptr, creature, damage));
  7079. return 1;
  7080. }
  7081.  
  7082. int LuaScriptInterface::luaCreatureGetMaxHealth(lua_State* L)
  7083. {
  7084. // creature:getMaxHealth()
  7085. const Creature* creature = getUserdata<const Creature>(L, 1);
  7086. if (creature) {
  7087. lua_pushnumber(L, creature->getMaxHealth());
  7088. } else {
  7089. lua_pushnil(L);
  7090. }
  7091. return 1;
  7092. }
  7093.  
  7094. int LuaScriptInterface::luaCreatureSetMaxHealth(lua_State* L)
  7095. {
  7096. // creature:setMaxHealth(maxHealth)
  7097. Creature* creature = getUserdata<Creature>(L, 1);
  7098. if (!creature) {
  7099. lua_pushnil(L);
  7100. return 1;
  7101. }
  7102.  
  7103. creature->healthMax = getNumber<uint32_t>(L, 2);
  7104. creature->health = std::min<int32_t>(creature->health, creature->healthMax);
  7105. g_game.addCreatureHealth(creature);
  7106.  
  7107. Player* player = creature->getPlayer();
  7108. if (player) {
  7109. player->sendStats();
  7110. }
  7111. pushBoolean(L, true);
  7112. return 1;
  7113. }
  7114.  
  7115. int LuaScriptInterface::luaCreatureSetHiddenHealth(lua_State* L)
  7116. {
  7117. // creature:setHiddenHealth(hide)
  7118. Creature* creature = getUserdata<Creature>(L, 1);
  7119. if (creature) {
  7120. creature->setHiddenHealth(getBoolean(L, 2));
  7121. g_game.addCreatureHealth(creature);
  7122. pushBoolean(L, true);
  7123. } else {
  7124. lua_pushnil(L);
  7125. }
  7126. return 1;
  7127. }
  7128.  
  7129. int LuaScriptInterface::luaCreatureGetMana(lua_State* L)
  7130. {
  7131. // creature:getMana()
  7132. const Creature* creature = getUserdata<const Creature>(L, 1);
  7133. if (creature) {
  7134. lua_pushnumber(L, creature->getMana());
  7135. } else {
  7136. lua_pushnil(L);
  7137. }
  7138. return 1;
  7139. }
  7140.  
  7141. int LuaScriptInterface::luaCreatureAddMana(lua_State* L)
  7142. {
  7143. // creature:addMana(manaChange[, animationOnLoss = false])
  7144. Creature* creature = getUserdata<Creature>(L, 1);
  7145. if (!creature) {
  7146. lua_pushnil(L);
  7147. return 1;
  7148. }
  7149.  
  7150. int32_t manaChange = getNumber<int32_t>(L, 2);
  7151. bool animationOnLoss = getBoolean(L, 3, false);
  7152. if (!animationOnLoss && manaChange < 0) {
  7153. creature->changeMana(manaChange);
  7154. } else {
  7155. g_game.combatChangeMana(nullptr, creature, manaChange, ORIGIN_NONE);
  7156. }
  7157. pushBoolean(L, true);
  7158. return 1;
  7159. }
  7160.  
  7161. int LuaScriptInterface::luaCreatureGetMaxMana(lua_State* L)
  7162. {
  7163. // creature:getMaxMana()
  7164. const Creature* creature = getUserdata<const Creature>(L, 1);
  7165. if (creature) {
  7166. lua_pushnumber(L, creature->getMaxMana());
  7167. } else {
  7168. lua_pushnil(L);
  7169. }
  7170. return 1;
  7171. }
  7172.  
  7173. int LuaScriptInterface::luaCreatureGetSkull(lua_State* L)
  7174. {
  7175. // creature:getSkull()
  7176. Creature* creature = getUserdata<Creature>(L, 1);
  7177. if (creature) {
  7178. lua_pushnumber(L, creature->getSkull());
  7179. } else {
  7180. lua_pushnil(L);
  7181. }
  7182. return 1;
  7183. }
  7184.  
  7185. int LuaScriptInterface::luaCreatureSetSkull(lua_State* L)
  7186. {
  7187. // creature:setSkull(skull)
  7188. Creature* creature = getUserdata<Creature>(L, 1);
  7189. if (creature) {
  7190. creature->setSkull(getNumber<Skulls_t>(L, 2));
  7191. pushBoolean(L, true);
  7192. } else {
  7193. lua_pushnil(L);
  7194. }
  7195. return 1;
  7196. }
  7197.  
  7198. int LuaScriptInterface::luaCreatureGetOutfit(lua_State* L)
  7199. {
  7200. // creature:getOutfit()
  7201. const Creature* creature = getUserdata<const Creature>(L, 1);
  7202. if (creature) {
  7203. pushOutfit(L, creature->getCurrentOutfit());
  7204. } else {
  7205. lua_pushnil(L);
  7206. }
  7207. return 1;
  7208. }
  7209.  
  7210. int LuaScriptInterface::luaCreatureSetOutfit(lua_State* L)
  7211. {
  7212. // creature:setOutfit(outfit)
  7213. Creature* creature = getUserdata<Creature>(L, 1);
  7214. if (creature) {
  7215. creature->defaultOutfit = getOutfit(L, 2);
  7216. g_game.internalCreatureChangeOutfit(creature, creature->defaultOutfit);
  7217. pushBoolean(L, true);
  7218. } else {
  7219. lua_pushnil(L);
  7220. }
  7221. return 1;
  7222. }
  7223.  
  7224. int LuaScriptInterface::luaCreatureGetCondition(lua_State* L)
  7225. {
  7226. // creature:getCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0]])
  7227. Creature* creature = getUserdata<Creature>(L, 1);
  7228. if (!creature) {
  7229. lua_pushnil(L);
  7230. return 1;
  7231. }
  7232.  
  7233. ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
  7234. ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
  7235. uint32_t subId = getNumber<uint32_t>(L, 4, 0);
  7236.  
  7237. Condition* condition = creature->getCondition(conditionType, conditionId, subId);
  7238. if (condition) {
  7239. pushUserdata<Condition>(L, condition);
  7240. setWeakMetatable(L, -1, "Condition");
  7241. } else {
  7242. lua_pushnil(L);
  7243. }
  7244. return 1;
  7245. }
  7246.  
  7247. int LuaScriptInterface::luaCreatureAddCondition(lua_State* L)
  7248. {
  7249. // creature:addCondition(condition[, force = false])
  7250. Creature* creature = getUserdata<Creature>(L, 1);
  7251. Condition* condition = getUserdata<Condition>(L, 2);
  7252. if (creature && condition) {
  7253. bool force = getBoolean(L, 3, false);
  7254. pushBoolean(L, creature->addCondition(condition->clone(), force));
  7255. } else {
  7256. lua_pushnil(L);
  7257. }
  7258. return 1;
  7259. }
  7260.  
  7261. int LuaScriptInterface::luaCreatureRemoveCondition(lua_State* L)
  7262. {
  7263. // creature:removeCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0[, force = false]]])
  7264. Creature* creature = getUserdata<Creature>(L, 1);
  7265. if (!creature) {
  7266. lua_pushnil(L);
  7267. return 1;
  7268. }
  7269.  
  7270. ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
  7271. ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
  7272. uint32_t subId = getNumber<uint32_t>(L, 4, 0);
  7273. Condition* condition = creature->getCondition(conditionType, conditionId, subId);
  7274. if (condition) {
  7275. bool force = getBoolean(L, 5, false);
  7276. creature->removeCondition(condition, force);
  7277. pushBoolean(L, true);
  7278. } else {
  7279. lua_pushnil(L);
  7280. }
  7281. return 1;
  7282. }
  7283.  
  7284. int LuaScriptInterface::luaCreatureRemove(lua_State* L)
  7285. {
  7286. // creature:remove()
  7287. Creature** creaturePtr = getRawUserdata<Creature>(L, 1);
  7288. if (!creaturePtr) {
  7289. lua_pushnil(L);
  7290. return 1;
  7291. }
  7292.  
  7293. Creature* creature = *creaturePtr;
  7294. if (!creature) {
  7295. lua_pushnil(L);
  7296. return 1;
  7297. }
  7298.  
  7299. Player* player = creature->getPlayer();
  7300. if (player) {
  7301. player->kickPlayer(true);
  7302. } else {
  7303. g_game.removeCreature(creature);
  7304. }
  7305.  
  7306. *creaturePtr = nullptr;
  7307. pushBoolean(L, true);
  7308. return 1;
  7309. }
  7310.  
  7311. int LuaScriptInterface::luaCreatureTeleportTo(lua_State* L)
  7312. {
  7313. // creature:teleportTo(position[, pushMovement = false])
  7314. bool pushMovement = getBoolean(L, 3, false);
  7315.  
  7316. const Position& position = getPosition(L, 2);
  7317. Creature* creature = getUserdata<Creature>(L, 1);
  7318. if (!creature) {
  7319. lua_pushnil(L);
  7320. return 1;
  7321. }
  7322.  
  7323. const Position oldPosition = creature->getPosition();
  7324. if (g_game.internalTeleport(creature, position, pushMovement) != RETURNVALUE_NOERROR) {
  7325. pushBoolean(L, false);
  7326. return 1;
  7327. }
  7328.  
  7329. if (!pushMovement) {
  7330. if (oldPosition.x == position.x) {
  7331. if (oldPosition.y < position.y) {
  7332. g_game.internalCreatureTurn(creature, DIRECTION_SOUTH);
  7333. } else {
  7334. g_game.internalCreatureTurn(creature, DIRECTION_NORTH);
  7335. }
  7336. } else if (oldPosition.x > position.x) {
  7337. g_game.internalCreatureTurn(creature, DIRECTION_WEST);
  7338. } else if (oldPosition.x < position.x) {
  7339. g_game.internalCreatureTurn(creature, DIRECTION_EAST);
  7340. }
  7341. }
  7342. pushBoolean(L, true);
  7343. return 1;
  7344. }
  7345.  
  7346. int LuaScriptInterface::luaCreatureSay(lua_State* L)
  7347. {
  7348. // creature:say(text, type[, ghost = false[, target = nullptr[, position]]])
  7349. int parameters = lua_gettop(L);
  7350.  
  7351. Position position;
  7352. if (parameters >= 6) {
  7353. position = getPosition(L, 6);
  7354. if (!position.x || !position.y) {
  7355. reportErrorFunc("Invalid position specified.");
  7356. pushBoolean(L, false);
  7357. return 1;
  7358. }
  7359. }
  7360.  
  7361. Creature* target = nullptr;
  7362. if (parameters >= 5) {
  7363. target = getCreature(L, 5);
  7364. }
  7365.  
  7366. bool ghost = getBoolean(L, 4, false);
  7367.  
  7368. SpeakClasses type = getNumber<SpeakClasses>(L, 3);
  7369. const std::string& text = getString(L, 2);
  7370. Creature* creature = getUserdata<Creature>(L, 1);
  7371. if (!creature) {
  7372. lua_pushnil(L);
  7373. return 1;
  7374. }
  7375.  
  7376. SpectatorVec list;
  7377. if (target) {
  7378. list.insert(target);
  7379. }
  7380.  
  7381. if (position.x != 0) {
  7382. pushBoolean(L, g_game.internalCreatureSay(creature, type, text, ghost, &list, &position));
  7383. } else {
  7384. pushBoolean(L, g_game.internalCreatureSay(creature, type, text, ghost, &list));
  7385. }
  7386. return 1;
  7387. }
  7388.  
  7389. int LuaScriptInterface::luaCreatureGetDamageMap(lua_State* L)
  7390. {
  7391. // creature:getDamageMap()
  7392. Creature* creature = getUserdata<Creature>(L, 1);
  7393. if (!creature) {
  7394. lua_pushnil(L);
  7395. return 1;
  7396. }
  7397.  
  7398. lua_createtable(L, creature->damageMap.size(), 0);
  7399. for (auto damageEntry : creature->damageMap) {
  7400. lua_createtable(L, 0, 2);
  7401. setField(L, "total", damageEntry.second.total);
  7402. setField(L, "ticks", damageEntry.second.ticks);
  7403. lua_rawseti(L, -2, damageEntry.first);
  7404. }
  7405. return 1;
  7406. }
  7407.  
  7408. int LuaScriptInterface::luaCreatureGetSummons(lua_State* L)
  7409. {
  7410. // creature:getSummons()
  7411. Creature* creature = getUserdata<Creature>(L, 1);
  7412. if (!creature) {
  7413. lua_pushnil(L);
  7414. return 1;
  7415. }
  7416.  
  7417. lua_createtable(L, creature->getSummonCount(), 0);
  7418.  
  7419. int index = 0;
  7420. for (Creature* summon : creature->getSummons()) {
  7421. pushUserdata<Creature>(L, summon);
  7422. setCreatureMetatable(L, -1, summon);
  7423. lua_rawseti(L, -2, ++index);
  7424. }
  7425. return 1;
  7426. }
  7427.  
  7428. int LuaScriptInterface::luaCreatureGetDescription(lua_State* L)
  7429. {
  7430. // creature:getDescription(distance)
  7431. int32_t distance = getNumber<int32_t>(L, 2);
  7432. Creature* creature = getUserdata<Creature>(L, 1);
  7433. if (creature) {
  7434. pushString(L, creature->getDescription(distance));
  7435. } else {
  7436. lua_pushnil(L);
  7437. }
  7438. return 1;
  7439. }
  7440.  
  7441. int LuaScriptInterface::luaCreatureGetPathTo(lua_State* L)
  7442. {
  7443. // creature:getPathTo(pos[, minTargetDist = 0[, maxTargetDist = 1[, fullPathSearch = true[, clearSight = true[, maxSearchDist = 0]]]]])
  7444. Creature* creature = getUserdata<Creature>(L, 1);
  7445. if (!creature) {
  7446. lua_pushnil(L);
  7447. return 1;
  7448. }
  7449.  
  7450. const Position& position = getPosition(L, 2);
  7451.  
  7452. FindPathParams fpp;
  7453. fpp.minTargetDist = getNumber<int32_t>(L, 3, 0);
  7454. fpp.maxTargetDist = getNumber<int32_t>(L, 4, 1);
  7455. fpp.fullPathSearch = getBoolean(L, 5, fpp.fullPathSearch);
  7456. fpp.clearSight = getBoolean(L, 6, fpp.clearSight);
  7457. fpp.maxSearchDist = getNumber<int32_t>(L, 7, fpp.maxSearchDist);
  7458.  
  7459. std::forward_list<Direction> dirList;
  7460. if (creature->getPathTo(position, dirList, fpp)) {
  7461. lua_newtable(L);
  7462.  
  7463. int index = 0;
  7464. for (Direction dir : dirList) {
  7465. lua_pushnumber(L, dir);
  7466. lua_rawseti(L, -2, ++index);
  7467. }
  7468. } else {
  7469. pushBoolean(L, false);
  7470. }
  7471. return 1;
  7472. }
  7473.  
  7474. // Player
  7475. int LuaScriptInterface::luaPlayerCreate(lua_State* L)
  7476. {
  7477. // Player(id or name or userdata)
  7478. Player* player;
  7479. if (isNumber(L, 2)) {
  7480. player = g_game.getPlayerByID(getNumber<uint32_t>(L, 2));
  7481. } else if (isString(L, 2)) {
  7482. ReturnValue ret = g_game.getPlayerByNameWildcard(getString(L, 2), player);
  7483. if (ret != RETURNVALUE_NOERROR) {
  7484. lua_pushnil(L);
  7485. lua_pushnumber(L, ret);
  7486. return 2;
  7487. }
  7488. } else if (isUserdata(L, 2)) {
  7489. if (getUserdataType(L, 2) != LuaData_Player) {
  7490. lua_pushnil(L);
  7491. return 1;
  7492. }
  7493. player = getUserdata<Player>(L, 2);
  7494. } else {
  7495. player = nullptr;
  7496. }
  7497.  
  7498. if (player) {
  7499. pushUserdata<Player>(L, player);
  7500. setMetatable(L, -1, "Player");
  7501. } else {
  7502. lua_pushnil(L);
  7503. }
  7504. return 1;
  7505. }
  7506.  
  7507. int LuaScriptInterface::luaPlayerIsPlayer(lua_State* L)
  7508. {
  7509. // player:isPlayer()
  7510. pushBoolean(L, getUserdata<const Player>(L, 1) != nullptr);
  7511. return 1;
  7512. }
  7513.  
  7514. int LuaScriptInterface::luaPlayerGetGuid(lua_State* L)
  7515. {
  7516. // player:getGuid()
  7517. Player* player = getUserdata<Player>(L, 1);
  7518. if (player) {
  7519. lua_pushnumber(L, player->getGUID());
  7520. } else {
  7521. lua_pushnil(L);
  7522. }
  7523. return 1;
  7524. }
  7525.  
  7526. int LuaScriptInterface::luaPlayerGetIp(lua_State* L)
  7527. {
  7528. // player:getIp()
  7529. Player* player = getUserdata<Player>(L, 1);
  7530. if (player) {
  7531. lua_pushnumber(L, player->getIP());
  7532. } else {
  7533. lua_pushnil(L);
  7534. }
  7535. return 1;
  7536. }
  7537.  
  7538. int LuaScriptInterface::luaPlayerGetAccountId(lua_State* L)
  7539. {
  7540. // player:getAccountId()
  7541. Player* player = getUserdata<Player>(L, 1);
  7542. if (player) {
  7543. lua_pushnumber(L, player->getAccount());
  7544. } else {
  7545. lua_pushnil(L);
  7546. }
  7547. return 1;
  7548. }
  7549.  
  7550. int LuaScriptInterface::luaPlayerGetLastLoginSaved(lua_State* L)
  7551. {
  7552. // player:getLastLoginSaved()
  7553. Player* player = getUserdata<Player>(L, 1);
  7554. if (player) {
  7555. lua_pushnumber(L, player->getLastLoginSaved());
  7556. } else {
  7557. lua_pushnil(L);
  7558. }
  7559. return 1;
  7560. }
  7561.  
  7562. int LuaScriptInterface::luaPlayerGetLastLogout(lua_State* L)
  7563. {
  7564. // player:getLastLogout()
  7565. Player* player = getUserdata<Player>(L, 1);
  7566. if (player) {
  7567. lua_pushnumber(L, player->getLastLogout());
  7568. } else {
  7569. lua_pushnil(L);
  7570. }
  7571. return 1;
  7572. }
  7573.  
  7574. int LuaScriptInterface::luaPlayerGetAccountType(lua_State* L)
  7575. {
  7576. // player:getAccountType()
  7577. Player* player = getUserdata<Player>(L, 1);
  7578. if (player) {
  7579. lua_pushnumber(L, player->getAccountType());
  7580. } else {
  7581. lua_pushnil(L);
  7582. }
  7583. return 1;
  7584. }
  7585.  
  7586. int LuaScriptInterface::luaPlayerSetAccountType(lua_State* L)
  7587. {
  7588. // player:setAccountType(accountType)
  7589. Player* player = getUserdata<Player>(L, 1);
  7590. if (player) {
  7591. player->accountType = getNumber<AccountType_t>(L, 2);
  7592. IOLoginData::setAccountType(player->getAccount(), player->accountType);
  7593. pushBoolean(L, true);
  7594. } else {
  7595. lua_pushnil(L);
  7596. }
  7597. return 1;
  7598. }
  7599.  
  7600. int LuaScriptInterface::luaPlayerGetCapacity(lua_State* L)
  7601. {
  7602. // player:getCapacity()
  7603. Player* player = getUserdata<Player>(L, 1);
  7604. if (player) {
  7605. lua_pushnumber(L, player->getCapacity());
  7606. } else {
  7607. lua_pushnil(L);
  7608. }
  7609. return 1;
  7610. }
  7611.  
  7612. int LuaScriptInterface::luaPlayerSetCapacity(lua_State* L)
  7613. {
  7614. // player:setCapacity(capacity)
  7615. Player* player = getUserdata<Player>(L, 1);
  7616. if (player) {
  7617. player->capacity = getNumber<uint32_t>(L, 2);
  7618. player->sendStats();
  7619. pushBoolean(L, true);
  7620. } else {
  7621. lua_pushnil(L);
  7622. }
  7623. return 1;
  7624. }
  7625.  
  7626. int LuaScriptInterface::luaPlayerGetFreeCapacity(lua_State* L)
  7627. {
  7628. // player:getFreeCapacity()
  7629. Player* player = getUserdata<Player>(L, 1);
  7630. if (player) {
  7631. lua_pushnumber(L, player->getFreeCapacity());
  7632. } else {
  7633. lua_pushnil(L);
  7634. }
  7635. return 1;
  7636. }
  7637.  
  7638. int LuaScriptInterface::luaPlayerGetReward(lua_State* L)
  7639. {
  7640. // player:getReward(rewardId[, autoCreate = false])
  7641. Player* player = getUserdata<Player>(L, 1);
  7642. if (!player) {
  7643. lua_pushnil(L);
  7644. return 1;
  7645. }
  7646.  
  7647. uint32_t rewardId = getNumber<uint32_t>(L, 2);
  7648. bool autoCreate = getBoolean(L, 3, false);
  7649. if (Reward* reward = player->getReward(rewardId, autoCreate)) {
  7650. pushUserdata<Item>(L, reward);
  7651. setItemMetatable(L, -1, reward);
  7652. } else {
  7653. pushBoolean(L, false);
  7654. }
  7655. return 1;
  7656. }
  7657.  
  7658. int LuaScriptInterface::luaPlayerRemoveReward(lua_State* L)
  7659. {
  7660. // player:removeReward(rewardId)
  7661. Player* player = getUserdata<Player>(L, 1);
  7662. if (!player) {
  7663. lua_pushnil(L);
  7664. return 1;
  7665. }
  7666.  
  7667. uint32_t rewardId = getNumber<uint32_t>(L, 2);
  7668. player->removeReward(rewardId);
  7669. pushBoolean(L, true);
  7670. return 1;
  7671. }
  7672.  
  7673. int LuaScriptInterface::luaPlayerGetRewardList(lua_State* L)
  7674. {
  7675. // player:getRewardList(rewardId)
  7676. Player* player = getUserdata<Player>(L, 1);
  7677. if (!player) {
  7678. lua_pushnil(L);
  7679. return 1;
  7680. }
  7681.  
  7682. auto rewardVec = player->getRewardList();
  7683. lua_createtable(L, rewardVec.size(), 0);
  7684.  
  7685. int index = 0;
  7686. for (const auto& rewardId : rewardVec) {
  7687. lua_pushnumber(L, rewardId);
  7688. lua_rawseti(L, -2, ++index);
  7689. }
  7690. return 1;
  7691. }
  7692.  
  7693. int LuaScriptInterface::luaPlayerGetDepotChest(lua_State* L)
  7694. {
  7695. // player:getDepotChest(depotId[, autoCreate = false])
  7696. Player* player = getUserdata<Player>(L, 1);
  7697. if (!player) {
  7698. lua_pushnil(L);
  7699. return 1;
  7700. }
  7701.  
  7702. uint32_t depotId = getNumber<uint32_t>(L, 2);
  7703. bool autoCreate = getBoolean(L, 3, false);
  7704. DepotChest* depotChest = player->getDepotChest(depotId, autoCreate);
  7705. if (depotChest) {
  7706. pushUserdata<Item>(L, depotChest);
  7707. setItemMetatable(L, -1, depotChest);
  7708. } else {
  7709. pushBoolean(L, false);
  7710. }
  7711. return 1;
  7712. }
  7713.  
  7714. int LuaScriptInterface::luaPlayerGetInbox(lua_State* L)
  7715. {
  7716. // player:getInbox()
  7717. Player* player = getUserdata<Player>(L, 1);
  7718. if (!player) {
  7719. lua_pushnil(L);
  7720. return 1;
  7721. }
  7722.  
  7723. Inbox* inbox = player->getInbox();
  7724. if (inbox) {
  7725. pushUserdata<Item>(L, inbox);
  7726. setItemMetatable(L, -1, inbox);
  7727. } else {
  7728. pushBoolean(L, false);
  7729. }
  7730. return 1;
  7731. }
  7732.  
  7733. int LuaScriptInterface::luaPlayerGetSkullTime(lua_State* L)
  7734. {
  7735. // player:getSkullTime()
  7736. Player* player = getUserdata<Player>(L, 1);
  7737. if (player) {
  7738. lua_pushnumber(L, player->getSkullTicks());
  7739. } else {
  7740. lua_pushnil(L);
  7741. }
  7742. return 1;
  7743. }
  7744.  
  7745. int LuaScriptInterface::luaPlayerSetSkullTime(lua_State* L)
  7746. {
  7747. // player:setSkullTime(skullTime)
  7748. Player* player = getUserdata<Player>(L, 1);
  7749. if (player) {
  7750. player->setSkullTicks(getNumber<int64_t>(L, 2));
  7751. pushBoolean(L, true);
  7752. } else {
  7753. lua_pushnil(L);
  7754. }
  7755. return 1;
  7756. }
  7757.  
  7758. int LuaScriptInterface::luaPlayerGetDeathPenalty(lua_State* L)
  7759. {
  7760. // player:getDeathPenalty()
  7761. Player* player = getUserdata<Player>(L, 1);
  7762. if (player) {
  7763. lua_pushnumber(L, static_cast<uint32_t>(player->getLostPercent() * 100));
  7764. } else {
  7765. lua_pushnil(L);
  7766. }
  7767. return 1;
  7768. }
  7769.  
  7770. int LuaScriptInterface::luaPlayerGetExperience(lua_State* L)
  7771. {
  7772. // player:getExperience()
  7773. Player* player = getUserdata<Player>(L, 1);
  7774. if (player) {
  7775. lua_pushnumber(L, player->getExperience());
  7776. } else {
  7777. lua_pushnil(L);
  7778. }
  7779. return 1;
  7780. }
  7781.  
  7782. int LuaScriptInterface::luaPlayerAddExperience(lua_State* L)
  7783. {
  7784. // player:addExperience(experience[, sendText = false])
  7785. Player* player = getUserdata<Player>(L, 1);
  7786. if (player) {
  7787. int64_t experience = getNumber<int64_t>(L, 2);
  7788. bool sendText = getBoolean(L, 3, false);
  7789. player->addExperience(nullptr, experience, sendText);
  7790. pushBoolean(L, true);
  7791. } else {
  7792. lua_pushnil(L);
  7793. }
  7794. return 1;
  7795. }
  7796.  
  7797. int LuaScriptInterface::luaPlayerRemoveExperience(lua_State* L)
  7798. {
  7799. // player:removeExperience(experience[, sendText = false])
  7800. Player* player = getUserdata<Player>(L, 1);
  7801. if (player) {
  7802. int64_t experience = getNumber<int64_t>(L, 2);
  7803. bool sendText = getBoolean(L, 3, false);
  7804. player->removeExperience(experience, sendText);
  7805. pushBoolean(L, true);
  7806. } else {
  7807. lua_pushnil(L);
  7808. }
  7809. return 1;
  7810. }
  7811.  
  7812. int LuaScriptInterface::luaPlayerGetLevel(lua_State* L)
  7813. {
  7814. // player:getLevel()
  7815. Player* player = getUserdata<Player>(L, 1);
  7816. if (player) {
  7817. lua_pushnumber(L, player->getLevel());
  7818. } else {
  7819. lua_pushnil(L);
  7820. }
  7821. return 1;
  7822. }
  7823.  
  7824. int LuaScriptInterface::luaPlayerGetMagicLevel(lua_State* L)
  7825. {
  7826. // player:getMagicLevel()
  7827. Player* player = getUserdata<Player>(L, 1);
  7828. if (player) {
  7829. lua_pushnumber(L, player->getMagicLevel());
  7830. } else {
  7831. lua_pushnil(L);
  7832. }
  7833. return 1;
  7834. }
  7835.  
  7836. int LuaScriptInterface::luaPlayerGetBaseMagicLevel(lua_State* L)
  7837. {
  7838. // player:getBaseMagicLevel()
  7839. Player* player = getUserdata<Player>(L, 1);
  7840. if (player) {
  7841. lua_pushnumber(L, player->getBaseMagicLevel());
  7842. } else {
  7843. lua_pushnil(L);
  7844. }
  7845. return 1;
  7846. }
  7847.  
  7848. int LuaScriptInterface::luaPlayerSetMaxMana(lua_State* L)
  7849. {
  7850. // player:setMaxMana(maxMana)
  7851. Player* player = getPlayer(L, 1);
  7852. if (player) {
  7853. player->manaMax = getNumber<int32_t>(L, 2);
  7854. player->mana = std::min<int32_t>(player->mana, player->manaMax);
  7855. player->sendStats();
  7856. pushBoolean(L, true);
  7857. } else {
  7858. lua_pushnil(L);
  7859. }
  7860. return 1;
  7861. }
  7862.  
  7863. int LuaScriptInterface::luaPlayerGetManaSpent(lua_State* L)
  7864. {
  7865. // player:getManaSpent()
  7866. Player* player = getUserdata<Player>(L, 1);
  7867. if (player) {
  7868. lua_pushnumber(L, player->getSpentMana());
  7869. } else {
  7870. lua_pushnil(L);
  7871. }
  7872. return 1;
  7873. }
  7874.  
  7875. int LuaScriptInterface::luaPlayerAddManaSpent(lua_State* L)
  7876. {
  7877. // player:addManaSpent(amount)
  7878. Player* player = getUserdata<Player>(L, 1);
  7879. if (player) {
  7880. player->addManaSpent(getNumber<uint64_t>(L, 2));
  7881. pushBoolean(L, true);
  7882. } else {
  7883. lua_pushnil(L);
  7884. }
  7885. return 1;
  7886. }
  7887.  
  7888. int LuaScriptInterface::luaPlayerGetSkillLevel(lua_State* L)
  7889. {
  7890. // player:getSkillLevel(skillType)
  7891. skills_t skillType = getNumber<skills_t>(L, 2);
  7892. Player* player = getUserdata<Player>(L, 1);
  7893. if (player && skillType <= SKILL_LAST) {
  7894. lua_pushnumber(L, player->skills[skillType].level);
  7895. } else {
  7896. lua_pushnil(L);
  7897. }
  7898. return 1;
  7899. }
  7900.  
  7901. int LuaScriptInterface::luaPlayerGetEffectiveSkillLevel(lua_State* L)
  7902. {
  7903. // player:getEffectiveSkillLevel(skillType)
  7904. skills_t skillType = getNumber<skills_t>(L, 2);
  7905. Player* player = getUserdata<Player>(L, 1);
  7906. if (player && skillType <= SKILL_LAST) {
  7907. lua_pushnumber(L, player->getSkillLevel(skillType));
  7908. } else {
  7909. lua_pushnil(L);
  7910. }
  7911. return 1;
  7912. }
  7913.  
  7914. int LuaScriptInterface::luaPlayerGetSkillPercent(lua_State* L)
  7915. {
  7916. // player:getSkillPercent(skillType)
  7917. skills_t skillType = getNumber<skills_t>(L, 2);
  7918. Player* player = getUserdata<Player>(L, 1);
  7919. if (player && skillType <= SKILL_LAST) {
  7920. lua_pushnumber(L, player->skills[skillType].percent);
  7921. } else {
  7922. lua_pushnil(L);
  7923. }
  7924. return 1;
  7925. }
  7926.  
  7927. int LuaScriptInterface::luaPlayerGetSkillTries(lua_State* L)
  7928. {
  7929. // player:getSkillTries(skillType)
  7930. skills_t skillType = getNumber<skills_t>(L, 2);
  7931. Player* player = getUserdata<Player>(L, 1);
  7932. if (player && skillType <= SKILL_LAST) {
  7933. lua_pushnumber(L, player->skills[skillType].tries);
  7934. } else {
  7935. lua_pushnil(L);
  7936. }
  7937. return 1;
  7938. }
  7939.  
  7940. int LuaScriptInterface::luaPlayerAddSkillTries(lua_State* L)
  7941. {
  7942. // player:addSkillTries(skillType, tries)
  7943. Player* player = getUserdata<Player>(L, 1);
  7944. if (player) {
  7945. skills_t skillType = getNumber<skills_t>(L, 2);
  7946. uint64_t tries = getNumber<uint64_t>(L, 3);
  7947. player->addSkillAdvance(skillType, tries);
  7948. pushBoolean(L, true);
  7949. } else {
  7950. lua_pushnil(L);
  7951. }
  7952. return 1;
  7953. }
  7954.  
  7955. int LuaScriptInterface::luaPlayerAddOfflineTrainingTime(lua_State* L)
  7956. {
  7957. // player:addOfflineTrainingTime(time)
  7958. Player* player = getUserdata<Player>(L, 1);
  7959. if (player) {
  7960. int32_t time = getNumber<int32_t>(L, 2);
  7961. player->addOfflineTrainingTime(time);
  7962. player->sendStats();
  7963. pushBoolean(L, true);
  7964. } else {
  7965. lua_pushnil(L);
  7966. }
  7967. return 1;
  7968. }
  7969.  
  7970.  
  7971. int LuaScriptInterface::luaPlayerGetOfflineTrainingTime(lua_State* L)
  7972. {
  7973. // player:getOfflineTrainingTime()
  7974. Player* player = getUserdata<Player>(L, 1);
  7975. if (player) {
  7976. lua_pushnumber(L, player->getOfflineTrainingTime());
  7977. } else {
  7978. lua_pushnil(L);
  7979. }
  7980. return 1;
  7981. }
  7982.  
  7983. int LuaScriptInterface::luaPlayerRemoveOfflineTrainingTime(lua_State* L)
  7984. {
  7985. // player:removeOfflineTrainingTime(time)
  7986. Player* player = getUserdata<Player>(L, 1);
  7987. if (player) {
  7988. int32_t time = getNumber<int32_t>(L, 2);
  7989. player->removeOfflineTrainingTime(time);
  7990. player->sendStats();
  7991. pushBoolean(L, true);
  7992. } else {
  7993. lua_pushnil(L);
  7994. }
  7995. return 1;
  7996. }
  7997.  
  7998. int LuaScriptInterface::luaPlayerAddOfflineTrainingTries(lua_State* L)
  7999. {
  8000. // player:addOfflineTrainingTries(skillType, tries)
  8001. Player* player = getUserdata<Player>(L, 1);
  8002. if (player) {
  8003. skills_t skillType = getNumber<skills_t>(L, 2);
  8004. uint64_t tries = getNumber<uint64_t>(L, 3);
  8005. pushBoolean(L, player->addOfflineTrainingTries(skillType, tries));
  8006. } else {
  8007. lua_pushnil(L);
  8008. }
  8009. return 1;
  8010. }
  8011.  
  8012. int LuaScriptInterface::luaPlayerGetOfflineTrainingSkill(lua_State* L)
  8013. {
  8014. // player:getOfflineTrainingSkill()
  8015. Player* player = getUserdata<Player>(L, 1);
  8016. if (player) {
  8017. lua_pushnumber(L, player->getOfflineTrainingSkill());
  8018. } else {
  8019. lua_pushnil(L);
  8020. }
  8021. return 1;
  8022. }
  8023.  
  8024. int LuaScriptInterface::luaPlayerSetOfflineTrainingSkill(lua_State* L)
  8025. {
  8026. // player:setOfflineTrainingSkill(skillId)
  8027. Player* player = getUserdata<Player>(L, 1);
  8028. if (player) {
  8029. uint32_t skillId = getNumber<uint32_t>(L, 2);
  8030. player->setOfflineTrainingSkill(skillId);
  8031. pushBoolean(L, true);
  8032. } else {
  8033. lua_pushnil(L);
  8034. }
  8035. return 1;
  8036. }
  8037.  
  8038. int LuaScriptInterface::luaPlayerGetItemCount(lua_State* L)
  8039. {
  8040. // player:getItemCount(itemId[, subType = -1])
  8041. Player* player = getUserdata<Player>(L, 1);
  8042. if (!player) {
  8043. lua_pushnil(L);
  8044. return 1;
  8045. }
  8046.  
  8047. uint16_t itemId;
  8048. if (isNumber(L, 2)) {
  8049. itemId = getNumber<uint16_t>(L, 2);
  8050. } else {
  8051. itemId = Item::items.getItemIdByName(getString(L, 2));
  8052. if (itemId == 0) {
  8053. lua_pushnil(L);
  8054. return 1;
  8055. }
  8056. }
  8057.  
  8058. int32_t subType = getNumber<int32_t>(L, 3, -1);
  8059. lua_pushnumber(L, player->getItemTypeCount(itemId, subType));
  8060. return 1;
  8061. }
  8062.  
  8063. int LuaScriptInterface::luaPlayerGetItemById(lua_State* L)
  8064. {
  8065. // player:getItemById(itemId, deepSearch[, subType = -1])
  8066. Player* player = getUserdata<Player>(L, 1);
  8067. if (!player) {
  8068. lua_pushnil(L);
  8069. return 1;
  8070. }
  8071.  
  8072. uint16_t itemId;
  8073. if (isNumber(L, 2)) {
  8074. itemId = getNumber<uint16_t>(L, 2);
  8075. } else {
  8076. itemId = Item::items.getItemIdByName(getString(L, 2));
  8077. if (itemId == 0) {
  8078. lua_pushnil(L);
  8079. return 1;
  8080. }
  8081. }
  8082. bool deepSearch = getBoolean(L, 3);
  8083. int32_t subType = getNumber<int32_t>(L, 4, -1);
  8084.  
  8085. Item* item = g_game.findItemOfType(player, itemId, deepSearch, subType);
  8086. if (item) {
  8087. pushUserdata<Item>(L, item);
  8088. setItemMetatable(L, -1, item);
  8089. } else {
  8090. lua_pushnil(L);
  8091. }
  8092. return 1;
  8093. }
  8094.  
  8095. int LuaScriptInterface::luaPlayerGetVocation(lua_State* L)
  8096. {
  8097. // player:getVocation()
  8098. Player* player = getUserdata<Player>(L, 1);
  8099. if (player) {
  8100. pushUserdata<Vocation>(L, player->getVocation());
  8101. setMetatable(L, -1, "Vocation");
  8102. } else {
  8103. lua_pushnil(L);
  8104. }
  8105. return 1;
  8106. }
  8107.  
  8108. int LuaScriptInterface::luaPlayerSetVocation(lua_State* L)
  8109. {
  8110. // player:setVocation(id or name or userdata)
  8111. Player* player = getUserdata<Player>(L, 1);
  8112. if (!player) {
  8113. lua_pushnil(L);
  8114. return 1;
  8115. }
  8116.  
  8117. Vocation* vocation;
  8118. if (isNumber(L, 2)) {
  8119. vocation = g_vocations.getVocation(getNumber<uint16_t>(L, 2));
  8120. } else if (isString(L, 2)) {
  8121. vocation = g_vocations.getVocation(g_vocations.getVocationId(getString(L, 2)));
  8122. } else if (isUserdata(L, 2)) {
  8123. vocation = getUserdata<Vocation>(L, 2);
  8124. } else {
  8125. vocation = nullptr;
  8126. }
  8127.  
  8128. if (!vocation) {
  8129. pushBoolean(L, false);
  8130. return 1;
  8131. }
  8132.  
  8133. player->setVocation(vocation->getId());
  8134. pushBoolean(L, true);
  8135. return 1;
  8136. }
  8137.  
  8138. int LuaScriptInterface::luaPlayerGetSex(lua_State* L)
  8139. {
  8140. // player:getSex()
  8141. Player* player = getUserdata<Player>(L, 1);
  8142. if (player) {
  8143. lua_pushnumber(L, player->getSex());
  8144. } else {
  8145. lua_pushnil(L);
  8146. }
  8147. return 1;
  8148. }
  8149.  
  8150. int LuaScriptInterface::luaPlayerSetSex(lua_State* L)
  8151. {
  8152. // player:setSex(newSex)
  8153. Player* player = getUserdata<Player>(L, 1);
  8154. if (player) {
  8155. PlayerSex_t newSex = getNumber<PlayerSex_t>(L, 2);
  8156. player->setSex(newSex);
  8157. pushBoolean(L, true);
  8158. } else {
  8159. lua_pushnil(L);
  8160. }
  8161. return 1;
  8162. }
  8163.  
  8164. int LuaScriptInterface::luaPlayerGetTown(lua_State* L)
  8165. {
  8166. // player:getTown()
  8167. Player* player = getUserdata<Player>(L, 1);
  8168. if (player) {
  8169. pushUserdata<Town>(L, player->getTown());
  8170. setMetatable(L, -1, "Town");
  8171. } else {
  8172. lua_pushnil(L);
  8173. }
  8174. return 1;
  8175. }
  8176.  
  8177. int LuaScriptInterface::luaPlayerSetTown(lua_State* L)
  8178. {
  8179. // player:setTown(town)
  8180. Town* town = getUserdata<Town>(L, 2);
  8181. if (!town) {
  8182. pushBoolean(L, false);
  8183. return 1;
  8184. }
  8185.  
  8186. Player* player = getUserdata<Player>(L, 1);
  8187. if (player) {
  8188. player->setTown(town);
  8189. pushBoolean(L, true);
  8190. } else {
  8191. lua_pushnil(L);
  8192. }
  8193. return 1;
  8194. }
  8195.  
  8196. int LuaScriptInterface::luaPlayerGetGuild(lua_State* L)
  8197. {
  8198. // player:getGuild()
  8199. Player* player = getUserdata<Player>(L, 1);
  8200. if (!player) {
  8201. lua_pushnil(L);
  8202. return 1;
  8203. }
  8204.  
  8205. Guild* guild = player->getGuild();
  8206. if (!guild) {
  8207. lua_pushnil(L);
  8208. return 1;
  8209. }
  8210.  
  8211. pushUserdata<Guild>(L, guild);
  8212. setMetatable(L, -1, "Guild");
  8213. return 1;
  8214. }
  8215.  
  8216. int LuaScriptInterface::luaPlayerSetGuild(lua_State* L)
  8217. {
  8218. // player:setGuild(guild)
  8219. Player* player = getUserdata<Player>(L, 1);
  8220. if (!player) {
  8221. lua_pushnil(L);
  8222. return 1;
  8223. }
  8224.  
  8225. player->setGuild(getUserdata<Guild>(L, 2));
  8226. pushBoolean(L, true);
  8227. return 1;
  8228. }
  8229.  
  8230. int LuaScriptInterface::luaPlayerGetGuildLevel(lua_State* L)
  8231. {
  8232. // player:getGuildLevel()
  8233. Player* player = getUserdata<Player>(L, 1);
  8234. if (player) {
  8235. lua_pushnumber(L, player->getGuildLevel());
  8236. } else {
  8237. lua_pushnil(L);
  8238. }
  8239. return 1;
  8240. }
  8241.  
  8242. int LuaScriptInterface::luaPlayerSetGuildLevel(lua_State* L)
  8243. {
  8244. // player:setGuildLevel(level)
  8245. uint8_t level = getNumber<uint8_t>(L, 2);
  8246. Player* player = getUserdata<Player>(L, 1);
  8247. if (player) {
  8248. player->setGuildLevel(level);
  8249. pushBoolean(L, true);
  8250. } else {
  8251. lua_pushnil(L);
  8252. }
  8253. return 1;
  8254. }
  8255.  
  8256. int LuaScriptInterface::luaPlayerGetGuildNick(lua_State* L)
  8257. {
  8258. // player:getGuildNick()
  8259. Player* player = getUserdata<Player>(L, 1);
  8260. if (player) {
  8261. pushString(L, player->getGuildNick());
  8262. } else {
  8263. lua_pushnil(L);
  8264. }
  8265. return 1;
  8266. }
  8267.  
  8268. int LuaScriptInterface::luaPlayerSetGuildNick(lua_State* L)
  8269. {
  8270. // player:setGuildNick(nick)
  8271. const std::string& nick = getString(L, 2);
  8272. Player* player = getUserdata<Player>(L, 1);
  8273. if (player) {
  8274. player->setGuildNick(nick);
  8275. pushBoolean(L, true);
  8276. } else {
  8277. lua_pushnil(L);
  8278. }
  8279. return 1;
  8280. }
  8281.  
  8282. int LuaScriptInterface::luaPlayerGetGroup(lua_State* L)
  8283. {
  8284. // player:getGroup()
  8285. Player* player = getUserdata<Player>(L, 1);
  8286. if (player) {
  8287. pushUserdata<Group>(L, player->getGroup());
  8288. setMetatable(L, -1, "Group");
  8289. } else {
  8290. lua_pushnil(L);
  8291. }
  8292. return 1;
  8293. }
  8294.  
  8295. int LuaScriptInterface::luaPlayerSetGroup(lua_State* L)
  8296. {
  8297. // player:setGroup(group)
  8298. Group* group = getUserdata<Group>(L, 2);
  8299. if (!group) {
  8300. pushBoolean(L, false);
  8301. return 1;
  8302. }
  8303.  
  8304. Player* player = getUserdata<Player>(L, 1);
  8305. if (player) {
  8306. player->setGroup(group);
  8307. pushBoolean(L, true);
  8308. } else {
  8309. lua_pushnil(L);
  8310. }
  8311. return 1;
  8312. }
  8313.  
  8314. int LuaScriptInterface::luaPlayerGetStamina(lua_State* L)
  8315. {
  8316. // player:getStamina()
  8317. Player* player = getUserdata<Player>(L, 1);
  8318. if (player) {
  8319. lua_pushnumber(L, player->getStaminaMinutes());
  8320. } else {
  8321. lua_pushnil(L);
  8322. }
  8323. return 1;
  8324. }
  8325.  
  8326. int LuaScriptInterface::luaPlayerSetStamina(lua_State* L)
  8327. {
  8328. // player:setStamina(stamina)
  8329. uint16_t stamina = getNumber<uint16_t>(L, 2);
  8330. Player* player = getUserdata<Player>(L, 1);
  8331. if (player) {
  8332. player->staminaMinutes = std::min<uint16_t>(2520, stamina);
  8333. player->sendStats();
  8334. } else {
  8335. lua_pushnil(L);
  8336. }
  8337. return 1;
  8338. }
  8339.  
  8340. int LuaScriptInterface::luaPlayerGetSoul(lua_State* L)
  8341. {
  8342. // player:getSoul()
  8343. Player* player = getUserdata<Player>(L, 1);
  8344. if (player) {
  8345. lua_pushnumber(L, player->getSoul());
  8346. } else {
  8347. lua_pushnil(L);
  8348. }
  8349. return 1;
  8350. }
  8351.  
  8352. int LuaScriptInterface::luaPlayerAddSoul(lua_State* L)
  8353. {
  8354. // player:addSoul(soulChange)
  8355. int32_t soulChange = getNumber<int32_t>(L, 2);
  8356. Player* player = getUserdata<Player>(L, 1);
  8357. if (player) {
  8358. player->changeSoul(soulChange);
  8359. pushBoolean(L, true);
  8360. } else {
  8361. lua_pushnil(L);
  8362. }
  8363. return 1;
  8364. }
  8365.  
  8366. int LuaScriptInterface::luaPlayerGetMaxSoul(lua_State* L)
  8367. {
  8368. // player:getMaxSoul()
  8369. Player* player = getUserdata<Player>(L, 1);
  8370. if (player && player->vocation) {
  8371. lua_pushnumber(L, player->vocation->getSoulMax());
  8372. } else {
  8373. lua_pushnil(L);
  8374. }
  8375. return 1;
  8376. }
  8377.  
  8378. int LuaScriptInterface::luaPlayerGetBankBalance(lua_State* L)
  8379. {
  8380. // player:getBankBalance()
  8381. Player* player = getUserdata<Player>(L, 1);
  8382. if (player) {
  8383. lua_pushnumber(L, player->getBankBalance());
  8384. } else {
  8385. lua_pushnil(L);
  8386. }
  8387. return 1;
  8388. }
  8389.  
  8390. int LuaScriptInterface::luaPlayerSetBankBalance(lua_State* L)
  8391. {
  8392. // player:setBankBalance(bankBalance)
  8393. Player* player = getUserdata<Player>(L, 1);
  8394. if (player) {
  8395. player->setBankBalance(getNumber<uint64_t>(L, 2));
  8396. pushBoolean(L, true);
  8397. } else {
  8398. lua_pushnil(L);
  8399. }
  8400. return 1;
  8401. }
  8402.  
  8403. int LuaScriptInterface::luaPlayerGetStorageValue(lua_State* L)
  8404. {
  8405. // player:getStorageValue(key)
  8406. Player* player = getUserdata<Player>(L, 1);
  8407. if (!player) {
  8408. lua_pushnil(L);
  8409. return 1;
  8410. }
  8411.  
  8412. uint32_t key = getNumber<uint32_t>(L, 2);
  8413. int32_t value;
  8414. if (player->getStorageValue(key, value)) {
  8415. lua_pushnumber(L, value);
  8416. } else {
  8417. lua_pushnumber(L, -1);
  8418. }
  8419. return 1;
  8420. }
  8421.  
  8422. int LuaScriptInterface::luaPlayerSetStorageValue(lua_State* L)
  8423. {
  8424. // player:setStorageValue(key, value)
  8425. int32_t value = getNumber<int32_t>(L, 3);
  8426. uint32_t key = getNumber<uint32_t>(L, 2);
  8427. Player* player = getUserdata<Player>(L, 1);
  8428. if (IS_IN_KEYRANGE(key, RESERVED_RANGE)) {
  8429. std::ostringstream ss;
  8430. ss << "Accessing reserved range: " << key;
  8431. reportErrorFunc(ss.str());
  8432. pushBoolean(L, false);
  8433. return 1;
  8434. }
  8435.  
  8436. if (player) {
  8437. player->addStorageValue(key, value);
  8438. pushBoolean(L, true);
  8439. } else {
  8440. lua_pushnil(L);
  8441. }
  8442. return 1;
  8443. }
  8444.  
  8445. int LuaScriptInterface::luaPlayerAddItem(lua_State* L)
  8446. {
  8447. // player:addItem(itemId[, count = 1[, canDropOnMap = true[, subType = 1[, slot = CONST_SLOT_WHEREEVER]]]])
  8448. Player* player = getUserdata<Player>(L, 1);
  8449. if (!player) {
  8450. pushBoolean(L, false);
  8451. return 1;
  8452. }
  8453.  
  8454. uint16_t itemId;
  8455. if (isNumber(L, 2)) {
  8456. itemId = getNumber<uint16_t>(L, 2);
  8457. } else {
  8458. itemId = Item::items.getItemIdByName(getString(L, 2));
  8459. if (itemId == 0) {
  8460. lua_pushnil(L);
  8461. return 1;
  8462. }
  8463. }
  8464.  
  8465. int32_t count = getNumber<int32_t>(L, 3, 1);
  8466. int32_t subType = getNumber<int32_t>(L, 5, 1);
  8467.  
  8468. const ItemType& it = Item::items[itemId];
  8469.  
  8470. int32_t itemCount = 1;
  8471. int parameters = lua_gettop(L);
  8472. if (parameters >= 4) {
  8473. itemCount = std::max<int32_t>(1, count);
  8474. } else if (it.hasSubType()) {
  8475. if (it.stackable) {
  8476. itemCount = std::ceil(count / 100.f);
  8477. }
  8478.  
  8479. subType = count;
  8480. } else {
  8481. itemCount = std::max<int32_t>(1, count);
  8482. }
  8483.  
  8484. bool hasTable = itemCount > 1;
  8485. if (hasTable) {
  8486. lua_newtable(L);
  8487. } else if (itemCount == 0) {
  8488. lua_pushnil(L);
  8489. return 1;
  8490. }
  8491.  
  8492. bool canDropOnMap = getBoolean(L, 4, true);
  8493. slots_t slot = getNumber<slots_t>(L, 6, CONST_SLOT_WHEREEVER);
  8494. for (int32_t i = 1; i <= itemCount; ++i) {
  8495. int32_t stackCount = subType;
  8496. if (it.stackable) {
  8497. stackCount = std::min<int32_t>(stackCount, 100);
  8498. subType -= stackCount;
  8499. }
  8500.  
  8501. Item* item = Item::CreateItem(itemId, stackCount);
  8502. if (!item) {
  8503. if (!hasTable) {
  8504. lua_pushnil(L);
  8505. }
  8506. return 1;
  8507. }
  8508.  
  8509. ReturnValue ret = g_game.internalPlayerAddItem(player, item, canDropOnMap, slot);
  8510. if (ret != RETURNVALUE_NOERROR) {
  8511. delete item;
  8512. if (!hasTable) {
  8513. lua_pushnil(L);
  8514. }
  8515. return 1;
  8516. }
  8517.  
  8518. if (hasTable) {
  8519. lua_pushnumber(L, i);
  8520. pushUserdata<Item>(L, item);
  8521. setItemMetatable(L, -1, item);
  8522. lua_settable(L, -3);
  8523. } else {
  8524. pushUserdata<Item>(L, item);
  8525. setItemMetatable(L, -1, item);
  8526. }
  8527. }
  8528. return 1;
  8529. }
  8530.  
  8531. int LuaScriptInterface::luaPlayerAddItemEx(lua_State* L)
  8532. {
  8533. // player:addItemEx(item[, canDropOnMap = false[, index = INDEX_WHEREEVER[, flags = 0]]])
  8534. // player:addItemEx(item[, canDropOnMap = true[, slot = CONST_SLOT_WHEREEVER]])
  8535. Item* item = getUserdata<Item>(L, 2);
  8536. if (!item) {
  8537. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  8538. pushBoolean(L, false);
  8539. return 1;
  8540. }
  8541.  
  8542. Player* player = getUserdata<Player>(L, 1);
  8543. if (!player) {
  8544. lua_pushnil(L);
  8545. return 1;
  8546. }
  8547.  
  8548. if (item->getParent() != VirtualCylinder::virtualCylinder) {
  8549. reportErrorFunc("Item already has a parent");
  8550. pushBoolean(L, false);
  8551. return 1;
  8552. }
  8553.  
  8554. bool canDropOnMap = getBoolean(L, 3, false);
  8555. ReturnValue returnValue;
  8556. if (canDropOnMap) {
  8557. slots_t slot = getNumber<slots_t>(L, 4, CONST_SLOT_WHEREEVER);
  8558. returnValue = g_game.internalPlayerAddItem(player, item, true, slot);
  8559. } else {
  8560. int32_t index = getNumber<int32_t>(L, 4, INDEX_WHEREEVER);
  8561. uint32_t flags = getNumber<uint32_t>(L, 5, 0);
  8562. returnValue = g_game.internalAddItem(player, item, index, flags);
  8563. }
  8564.  
  8565. if (returnValue == RETURNVALUE_NOERROR) {
  8566. ScriptEnvironment::removeTempItem(item);
  8567. }
  8568. lua_pushnumber(L, returnValue);
  8569. return 1;
  8570. }
  8571.  
  8572. int LuaScriptInterface::luaPlayerRemoveItem(lua_State* L)
  8573. {
  8574. // player:removeItem(itemId, count[, subType = -1[, ignoreEquipped = false]])
  8575. Player* player = getUserdata<Player>(L, 1);
  8576. if (!player) {
  8577. lua_pushnil(L);
  8578. return 1;
  8579. }
  8580.  
  8581. uint16_t itemId;
  8582. if (isNumber(L, 2)) {
  8583. itemId = getNumber<uint16_t>(L, 2);
  8584. } else {
  8585. itemId = Item::items.getItemIdByName(getString(L, 2));
  8586. if (itemId == 0) {
  8587. lua_pushnil(L);
  8588. return 1;
  8589. }
  8590. }
  8591.  
  8592. uint32_t count = getNumber<uint32_t>(L, 3);
  8593. int32_t subType = getNumber<int32_t>(L, 4, -1);
  8594. bool ignoreEquipped = getBoolean(L, 5, false);
  8595. pushBoolean(L, player->removeItemOfType(itemId, count, subType, ignoreEquipped));
  8596. return 1;
  8597. }
  8598.  
  8599. int LuaScriptInterface::luaPlayerGetMoney(lua_State* L)
  8600. {
  8601. // player:getMoney()
  8602. Player* player = getUserdata<Player>(L, 1);
  8603. if (player) {
  8604. lua_pushnumber(L, player->getMoney());
  8605. } else {
  8606. lua_pushnil(L);
  8607. }
  8608. return 1;
  8609. }
  8610.  
  8611. int LuaScriptInterface::luaPlayerAddMoney(lua_State* L)
  8612. {
  8613. // player:addMoney(money)
  8614. uint64_t money = getNumber<uint64_t>(L, 2);
  8615. Player* player = getUserdata<Player>(L, 1);
  8616. if (player) {
  8617. g_game.addMoney(player, money);
  8618. pushBoolean(L, true);
  8619. } else {
  8620. lua_pushnil(L);
  8621. }
  8622. return 1;
  8623. }
  8624.  
  8625. int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L)
  8626. {
  8627. // player:removeMoney(money)mon
  8628. Player* player = getUserdata<Player>(L, 1);
  8629. bool success = false;
  8630. if (player) {
  8631. uint64_t money = getNumber<uint64_t>(L, 2);
  8632. if (!g_game.removeMoney(player, money))
  8633. {
  8634. uint64_t playerTotal = player->getMoney() + player->getBankBalance();
  8635.  
  8636. if (playerTotal >= money)
  8637. {
  8638. money -= player->getMoney(); //discount player money
  8639. if (money < 0) money = 0;
  8640. g_game.removeMoney(player, player->getMoney()); //1
  8641. if (player->getMoney() < 0) money = 0;
  8642. // player money is 0, and its value is discounted. Now remove from balance the rest
  8643. playerTotal = player->getBankBalance() - money;
  8644. if (playerTotal < 0) playerTotal = 0;
  8645. player->setBankBalance(playerTotal);
  8646. std::ostringstream ss;
  8647. ss << "Paid " << money << " gold from bank account. Your account balance is now " << player->getBankBalance() << " gold.";
  8648. player->sendTextMessage(MESSAGE_INFO_DESCR, ss.str());
  8649. success = true;
  8650. }
  8651. }
  8652. else
  8653. {
  8654. success = true;
  8655. }
  8656. pushBoolean(L, success);
  8657. } else {
  8658. lua_pushnil(L);
  8659. }
  8660. return 1;
  8661. }
  8662.  
  8663. int LuaScriptInterface::luaPlayerShowTextDialog(lua_State* L)
  8664. {
  8665. // player:showTextDialog(itemId[, text[, canWrite[, length]]])
  8666. Player* player = getUserdata<Player>(L, 1);
  8667. if (!player) {
  8668. lua_pushnil(L);
  8669. return 1;
  8670. }
  8671.  
  8672. int32_t length = getNumber<int32_t>(L, 5, -1);
  8673. bool canWrite = getBoolean(L, 4, false);
  8674. std::string text;
  8675.  
  8676. int parameters = lua_gettop(L);
  8677. if (parameters >= 3) {
  8678. text = getString(L, 3);
  8679. }
  8680.  
  8681. uint16_t itemId;
  8682. if (isNumber(L, 2)) {
  8683. itemId = getNumber<uint16_t>(L, 2);
  8684. } else {
  8685. itemId = Item::items.getItemIdByName(getString(L, 2));
  8686. if (itemId == 0) {
  8687. lua_pushnil(L);
  8688. return 1;
  8689. }
  8690. }
  8691.  
  8692. Item* item = Item::CreateItem(itemId);
  8693. if (!item) {
  8694. reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  8695. pushBoolean(L, false);
  8696. return 1;
  8697. }
  8698.  
  8699. if (length < 0) {
  8700. length = Item::items[item->getID()].maxTextLen;
  8701. }
  8702.  
  8703. if (!text.empty()) {
  8704. item->setText(text);
  8705. length = std::max<int32_t>(text.size(), length);
  8706. }
  8707.  
  8708. item->setParent(player);
  8709. player->setWriteItem(item, length);
  8710. player->sendTextWindow(item, length, canWrite);
  8711. pushBoolean(L, true);
  8712. return 1;
  8713. }
  8714.  
  8715. int LuaScriptInterface::luaPlayerSendTextMessage(lua_State* L)
  8716. {
  8717. // player:sendTextMessage(type, text[, position, primaryValue = 0, primaryColor = TEXTCOLOR_NONE[, secondaryValue = 0, secondaryColor = TEXTCOLOR_NONE]])
  8718. int parameters = lua_gettop(L);
  8719.  
  8720. TextMessage message(getNumber<MessageClasses>(L, 2), getString(L, 3));
  8721. if (parameters >= 6) {
  8722. message.position = getPosition(L, 4);
  8723. message.primary.value = getNumber<int32_t>(L, 5);
  8724. message.primary.color = getNumber<TextColor_t>(L, 6);
  8725. }
  8726.  
  8727. if (parameters >= 8) {
  8728. message.secondary.value = getNumber<int32_t>(L, 7);
  8729. message.secondary.color = getNumber<TextColor_t>(L, 8);
  8730. }
  8731.  
  8732. Player* player = getUserdata<Player>(L, 1);
  8733. if (player) {
  8734. player->sendTextMessage(message);
  8735. pushBoolean(L, true);
  8736. } else {
  8737. lua_pushnil(L);
  8738. }
  8739. return 1;
  8740. }
  8741.  
  8742. int LuaScriptInterface::luaPlayerSendChannelMessage(lua_State* L)
  8743. {
  8744. // player:sendChannelMessage(author, text, type, channelId)
  8745. uint16_t channelId = getNumber<uint16_t>(L, 5);
  8746. SpeakClasses type = getNumber<SpeakClasses>(L, 4);
  8747. const std::string& text = getString(L, 3);
  8748. const std::string& author = getString(L, 2);
  8749. Player* player = getUserdata<Player>(L, 1);
  8750. if (player) {
  8751. player->sendChannelMessage(author, text, type, channelId);
  8752. pushBoolean(L, true);
  8753. } else {
  8754. lua_pushnil(L);
  8755. }
  8756. return 1;
  8757. }
  8758.  
  8759. int LuaScriptInterface::luaPlayerSendPrivateMessage(lua_State* L)
  8760. {
  8761. // player:sendPrivateMessage(speaker, text[, type])
  8762. Player* player = getUserdata<Player>(L, 1);
  8763. if (!player) {
  8764. lua_pushnil(L);
  8765. return 1;
  8766. }
  8767.  
  8768. const Player* speaker = getUserdata<const Player>(L, 2);
  8769. const std::string& text = getString(L, 3);
  8770. SpeakClasses type = getNumber<SpeakClasses>(L, 4, TALKTYPE_PRIVATE_FROM);
  8771. player->sendPrivateMessage(speaker, type, text);
  8772. pushBoolean(L, true);
  8773. return 1;
  8774. }
  8775.  
  8776. int LuaScriptInterface::luaPlayerChannelSay(lua_State* L)
  8777. {
  8778. // player:channelSay(speaker, type, text, channelId)
  8779. Player* player = getUserdata<Player>(L, 1);
  8780. if (!player) {
  8781. lua_pushnil(L);
  8782. return 1;
  8783. }
  8784.  
  8785. Creature* speaker = getCreature(L, 2);
  8786. SpeakClasses type = getNumber<SpeakClasses>(L, 3);
  8787. const std::string& text = getString(L, 4);
  8788. uint16_t channelId = getNumber<uint16_t>(L, 5);
  8789. player->sendToChannel(speaker, type, text, channelId);
  8790. pushBoolean(L, true);
  8791. return 1;
  8792. }
  8793.  
  8794. int LuaScriptInterface::luaPlayerOpenChannel(lua_State* L)
  8795. {
  8796. // player:openChannel(channelId)
  8797. uint16_t channelId = getNumber<uint16_t>(L, 2);
  8798. Player* player = getUserdata<Player>(L, 1);
  8799. if (player) {
  8800. g_game.playerOpenChannel(player->getID(), channelId);
  8801. pushBoolean(L, true);
  8802. } else {
  8803. lua_pushnil(L);
  8804. }
  8805. return 1;
  8806. }
  8807.  
  8808. int LuaScriptInterface::luaPlayerGetSlotItem(lua_State* L)
  8809. {
  8810. // player:getSlotItem(slot)
  8811. const Player* player = getUserdata<const Player>(L, 1);
  8812. if (!player) {
  8813. lua_pushnil(L);
  8814. return 1;
  8815. }
  8816.  
  8817. uint32_t slot = getNumber<uint32_t>(L, 2);
  8818. Thing* thing = player->getThing(slot);
  8819. if (!thing) {
  8820. lua_pushnil(L);
  8821. return 1;
  8822. }
  8823.  
  8824. Item* item = thing->getItem();
  8825. if (item) {
  8826. pushUserdata<Item>(L, item);
  8827. setItemMetatable(L, -1, item);
  8828. } else {
  8829. lua_pushnil(L);
  8830. }
  8831. return 1;
  8832. }
  8833.  
  8834. int LuaScriptInterface::luaPlayerGetParty(lua_State* L)
  8835. {
  8836. // player:getParty()
  8837. const Player* player = getUserdata<const Player>(L, 1);
  8838. if (!player) {
  8839. lua_pushnil(L);
  8840. return 1;
  8841. }
  8842.  
  8843. Party* party = player->getParty();
  8844. if (party) {
  8845. pushUserdata<Party>(L, party);
  8846. setMetatable(L, -1, "Party");
  8847. } else {
  8848. lua_pushnil(L);
  8849. }
  8850. return 1;
  8851. }
  8852.  
  8853. int LuaScriptInterface::luaPlayerAddOutfit(lua_State* L)
  8854. {
  8855. // player:addOutfit(lookType)
  8856. Player* player = getUserdata<Player>(L, 1);
  8857. if (player) {
  8858. player->addOutfit(getNumber<uint16_t>(L, 2), 0);
  8859. pushBoolean(L, true);
  8860. } else {
  8861. lua_pushnil(L);
  8862. }
  8863. return 1;
  8864. }
  8865.  
  8866. int LuaScriptInterface::luaPlayerAddOutfitAddon(lua_State* L)
  8867. {
  8868. // player:addOutfitAddon(lookType, addon)
  8869. Player* player = getUserdata<Player>(L, 1);
  8870. if (player) {
  8871. uint16_t lookType = getNumber<uint16_t>(L, 2);
  8872. uint8_t addon = getNumber<uint8_t>(L, 3);
  8873. player->addOutfit(lookType, addon);
  8874. pushBoolean(L, true);
  8875. } else {
  8876. lua_pushnil(L);
  8877. }
  8878. return 1;
  8879. }
  8880.  
  8881. int LuaScriptInterface::luaPlayerRemoveOutfit(lua_State* L)
  8882. {
  8883. // player:removeOutfit(lookType)
  8884. Player* player = getUserdata<Player>(L, 1);
  8885. if (player) {
  8886. uint16_t lookType = getNumber<uint16_t>(L, 2);
  8887. pushBoolean(L, player->removeOutfit(lookType));
  8888. } else {
  8889. lua_pushnil(L);
  8890. }
  8891. return 1;
  8892. }
  8893.  
  8894. int LuaScriptInterface::luaPlayerRemoveOutfitAddon(lua_State* L)
  8895. {
  8896. // player:removeOutfitAddon(lookType, addon)
  8897. Player* player = getUserdata<Player>(L, 1);
  8898. if (player) {
  8899. uint16_t lookType = getNumber<uint16_t>(L, 2);
  8900. uint8_t addon = getNumber<uint8_t>(L, 3);
  8901. pushBoolean(L, player->removeOutfitAddon(lookType, addon));
  8902. } else {
  8903. lua_pushnil(L);
  8904. }
  8905. return 1;
  8906. }
  8907.  
  8908. int LuaScriptInterface::luaPlayerHasOutfit(lua_State* L)
  8909. {
  8910. // player:hasOutfit(lookType[, addon = 0])
  8911. Player* player = getUserdata<Player>(L, 1);
  8912. if (player) {
  8913. uint16_t lookType = getNumber<uint16_t>(L, 2);
  8914. uint8_t addon = getNumber<uint8_t>(L, 3, 0);
  8915. pushBoolean(L, player->canWear(lookType, addon));
  8916. } else {
  8917. lua_pushnil(L);
  8918. }
  8919. return 1;
  8920. }
  8921.  
  8922. int LuaScriptInterface::luaPlayerSendOutfitWindow(lua_State* L)
  8923. {
  8924. // player:sendOutfitWindow()
  8925. Player* player = getUserdata<Player>(L, 1);
  8926. if (player) {
  8927. player->sendOutfitWindow();
  8928. pushBoolean(L, true);
  8929. } else {
  8930. lua_pushnil(L);
  8931. }
  8932. return 1;
  8933. }
  8934.  
  8935. int LuaScriptInterface::luaPlayerAddMount(lua_State* L)
  8936. {
  8937. // player:addMount(mountId or mountName)
  8938. Player* player = getUserdata<Player>(L, 1);
  8939. if (player) {
  8940. uint8_t mountId;
  8941. if (isNumber(L, 2)) {
  8942. mountId = getNumber<uint8_t>(L, 2);
  8943. pushBoolean(L, player->tameMount(mountId));
  8944. } else if (isString(L, 2)) {
  8945. Mount* mount = g_game.mounts.getMountByName(getString(L, 2));
  8946. if (!mount) {
  8947. lua_pushnil(L);
  8948. return 1;
  8949. }
  8950. mountId = mount->id;
  8951. pushBoolean(L, player->tameMount(mountId));
  8952. }
  8953. } else {
  8954. lua_pushnil(L);
  8955. }
  8956. return 1;
  8957. }
  8958.  
  8959. int LuaScriptInterface::luaPlayerRemoveMount(lua_State* L)
  8960. {
  8961. // player:removeMount(mountId or mountName)
  8962. Player* player = getUserdata<Player>(L, 1);
  8963. if (player) {
  8964. uint8_t mountId;
  8965. if (isNumber(L, 2)) {
  8966. mountId = getNumber<uint8_t>(L, 2);
  8967. pushBoolean(L, player->untameMount(mountId));
  8968. } else if (isString(L, 2)) {
  8969. Mount* mount = g_game.mounts.getMountByName(getString(L, 2));
  8970. if (!mount) {
  8971. lua_pushnil(L);
  8972. return 1;
  8973. }
  8974. mountId = mount->id;
  8975. pushBoolean(L, player->untameMount(mountId));
  8976. }
  8977.  
  8978. } else {
  8979. lua_pushnil(L);
  8980. }
  8981. return 1;
  8982. }
  8983.  
  8984. int LuaScriptInterface::luaPlayerHasMount(lua_State* L)
  8985. {
  8986. // player:hasMount(mountId or mountName)
  8987. const Player* player = getUserdata<const Player>(L, 1);
  8988. if (!player) {
  8989. lua_pushnil(L);
  8990. return 1;
  8991. }
  8992.  
  8993. Mount* mount = nullptr;
  8994. if (isNumber(L, 2)) {
  8995. mount = g_game.mounts.getMountByID(getNumber<uint8_t>(L, 2));
  8996. } else if (isString(L, 2)) {
  8997. mount = g_game.mounts.getMountByName(getString(L, 2));
  8998. }
  8999.  
  9000. if (mount) {
  9001. pushBoolean(L, player->hasMount(mount));
  9002. } else {
  9003. lua_pushnil(L);
  9004. }
  9005. return 1;
  9006. }
  9007.  
  9008. int LuaScriptInterface::luaPlayerGetPremiumDays(lua_State* L)
  9009. {
  9010. // player:getPremiumDays()
  9011. Player* player = getUserdata<Player>(L, 1);
  9012. if (player) {
  9013. lua_pushnumber(L, player->premiumDays);
  9014. } else {
  9015. lua_pushnil(L);
  9016. }
  9017. return 1;
  9018. }
  9019.  
  9020. int LuaScriptInterface::luaPlayerAddPremiumDays(lua_State* L)
  9021. {
  9022. // player:addPremiumDays(days)
  9023. Player* player = getUserdata<Player>(L, 1);
  9024. if (!player) {
  9025. lua_pushnil(L);
  9026. return 1;
  9027. }
  9028.  
  9029. if (player->premiumDays != std::numeric_limits<uint16_t>::max()) {
  9030. uint16_t days = getNumber<uint16_t>(L, 2);
  9031. int32_t addDays = std::min<int32_t>(0xFFFE - player->premiumDays, days);
  9032. if (addDays > 0) {
  9033. player->setPremiumDays(player->premiumDays + addDays);
  9034. IOLoginData::addPremiumDays(player->getAccount(), addDays);
  9035. }
  9036. }
  9037. pushBoolean(L, true);
  9038. return 1;
  9039. }
  9040.  
  9041. int LuaScriptInterface::luaPlayerRemovePremiumDays(lua_State* L)
  9042. {
  9043. // player:removePremiumDays(days)
  9044. Player* player = getUserdata<Player>(L, 1);
  9045. if (!player) {
  9046. lua_pushnil(L);
  9047. return 1;
  9048. }
  9049.  
  9050. if (player->premiumDays != std::numeric_limits<uint16_t>::max()) {
  9051. uint16_t days = getNumber<uint16_t>(L, 2);
  9052. int32_t removeDays = std::min<int32_t>(player->premiumDays, days);
  9053. if (removeDays > 0) {
  9054. player->setPremiumDays(player->premiumDays - removeDays);
  9055. IOLoginData::removePremiumDays(player->getAccount(), removeDays);
  9056. }
  9057. }
  9058. pushBoolean(L, true);
  9059. return 1;
  9060. }
  9061.  
  9062. int LuaScriptInterface::luaPlayerHasBlessing(lua_State* L)
  9063. {
  9064. // player:hasBlessing(blessing)
  9065. uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
  9066. Player* player = getUserdata<Player>(L, 1);
  9067. if (player) {
  9068. pushBoolean(L, player->hasBlessing(blessing));
  9069. } else {
  9070. lua_pushnil(L);
  9071. }
  9072. return 1;
  9073. }
  9074.  
  9075. int LuaScriptInterface::luaPlayerAddBlessing(lua_State* L)
  9076. {
  9077. // player:addBlessing(blessing)
  9078. Player* player = getUserdata<Player>(L, 1);
  9079. if (!player) {
  9080. lua_pushnil(L);
  9081. return 1;
  9082. }
  9083.  
  9084. uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
  9085. if (player->hasBlessing(blessing)) {
  9086. pushBoolean(L, false);
  9087. return 1;
  9088. }
  9089.  
  9090. player->addBlessing(1 << blessing);
  9091. pushBoolean(L, true);
  9092. return 1;
  9093. }
  9094.  
  9095. int LuaScriptInterface::luaPlayerRemoveBlessing(lua_State* L)
  9096. {
  9097. // player:removeBlessing(blessing)
  9098. Player* player = getUserdata<Player>(L, 1);
  9099. if (!player) {
  9100. lua_pushnil(L);
  9101. return 1;
  9102. }
  9103.  
  9104. uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
  9105. if (!player->hasBlessing(blessing)) {
  9106. pushBoolean(L, false);
  9107. return 1;
  9108. }
  9109.  
  9110. player->removeBlessing(1 << blessing);
  9111. pushBoolean(L, true);
  9112. return 1;
  9113. }
  9114.  
  9115. int LuaScriptInterface::luaPlayerCanLearnSpell(lua_State* L)
  9116. {
  9117. // player:canLearnSpell(spellName)
  9118. const Player* player = getUserdata<const Player>(L, 1);
  9119. if (!player) {
  9120. lua_pushnil(L);
  9121. return 1;
  9122. }
  9123.  
  9124. const std::string& spellName = getString(L, 2);
  9125. InstantSpell* spell = g_spells->getInstantSpellByName(spellName);
  9126. if (!spell) {
  9127. reportErrorFunc("Spell \"" + spellName + "\" not found");
  9128. pushBoolean(L, false);
  9129. return 1;
  9130. }
  9131.  
  9132. if (player->hasFlag(PlayerFlag_IgnoreSpellCheck)) {
  9133. pushBoolean(L, true);
  9134. return 1;
  9135. }
  9136.  
  9137. const auto& vocMap = spell->getVocMap();
  9138. if (vocMap.count(player->getVocationId()) == 0) {
  9139. pushBoolean(L, false);
  9140. } else if (player->getLevel() < spell->getLevel()) {
  9141. pushBoolean(L, false);
  9142. } else if (player->getMagicLevel() < spell->getMagicLevel()) {
  9143. pushBoolean(L, false);
  9144. } else {
  9145. pushBoolean(L, true);
  9146. }
  9147. return 1;
  9148. }
  9149.  
  9150. int LuaScriptInterface::luaPlayerLearnSpell(lua_State* L)
  9151. {
  9152. // player:learnSpell(spellName)
  9153. Player* player = getUserdata<Player>(L, 1);
  9154. if (player) {
  9155. const std::string& spellName = getString(L, 2);
  9156. player->learnInstantSpell(spellName);
  9157. pushBoolean(L, true);
  9158. } else {
  9159. lua_pushnil(L);
  9160. }
  9161. return 1;
  9162. }
  9163.  
  9164. int LuaScriptInterface::luaPlayerForgetSpell(lua_State* L)
  9165. {
  9166. // player:forgetSpell(spellName)
  9167. Player* player = getUserdata<Player>(L, 1);
  9168. if (player) {
  9169. const std::string& spellName = getString(L, 2);
  9170. player->forgetInstantSpell(spellName);
  9171. pushBoolean(L, true);
  9172. } else {
  9173. lua_pushnil(L);
  9174. }
  9175. return 1;
  9176. }
  9177.  
  9178. int LuaScriptInterface::luaPlayerHasLearnedSpell(lua_State* L)
  9179. {
  9180. // player:hasLearnedSpell(spellName)
  9181. Player* player = getUserdata<Player>(L, 1);
  9182. if (player) {
  9183. const std::string& spellName = getString(L, 2);
  9184. pushBoolean(L, player->hasLearnedInstantSpell(spellName));
  9185. } else {
  9186. lua_pushnil(L);
  9187. }
  9188. return 1;
  9189. }
  9190.  
  9191. int LuaScriptInterface::luaPlayerSendTutorial(lua_State* L)
  9192. {
  9193. // player:sendTutorial(tutorialId)
  9194. Player* player = getUserdata<Player>(L, 1);
  9195. if (player) {
  9196. uint8_t tutorialId = getNumber<uint8_t>(L, 2);
  9197. player->sendTutorial(tutorialId);
  9198. pushBoolean(L, true);
  9199. } else {
  9200. lua_pushnil(L);
  9201. }
  9202. return 1;
  9203. }
  9204.  
  9205. int LuaScriptInterface::luaPlayerAddMapMark(lua_State* L)
  9206. {
  9207. // player:addMapMark(position, type, description)
  9208. Player* player = getUserdata<Player>(L, 1);
  9209. if (player) {
  9210. const Position& position = getPosition(L, 2);
  9211. uint8_t type = getNumber<uint8_t>(L, 3);
  9212. const std::string& description = getString(L, 4);
  9213. player->sendAddMarker(position, type, description);
  9214. pushBoolean(L, true);
  9215. } else {
  9216. lua_pushnil(L);
  9217. }
  9218. return 1;
  9219. }
  9220.  
  9221. int LuaScriptInterface::luaPlayerSave(lua_State* L)
  9222. {
  9223. // player:save()
  9224. Player* player = getUserdata<Player>(L, 1);
  9225. if (player) {
  9226. player->loginPosition = player->getPosition();
  9227. pushBoolean(L, IOLoginData::savePlayer(player));
  9228. } else {
  9229. lua_pushnil(L);
  9230. }
  9231. return 1;
  9232. }
  9233.  
  9234. int LuaScriptInterface::luaPlayerPopupFYI(lua_State* L)
  9235. {
  9236. // player:popupFYI(message)
  9237. Player* player = getUserdata<Player>(L, 1);
  9238. if (player) {
  9239. const std::string& message = getString(L, 2);
  9240. player->sendFYIBox(message);
  9241. pushBoolean(L, true);
  9242. } else {
  9243. lua_pushnil(L);
  9244. }
  9245. return 1;
  9246. }
  9247.  
  9248. int LuaScriptInterface::luaPlayerIsPzLocked(lua_State* L)
  9249. {
  9250. // player:isPzLocked()
  9251. Player* player = getUserdata<Player>(L, 1);
  9252. if (player) {
  9253. pushBoolean(L, player->isPzLocked());
  9254. } else {
  9255. lua_pushnil(L);
  9256. }
  9257. return 1;
  9258. }
  9259.  
  9260. int LuaScriptInterface::luaPlayerGetClient(lua_State* L)
  9261. {
  9262. // player:getClient()
  9263. Player* player = getUserdata<Player>(L, 1);
  9264. if (player) {
  9265. lua_createtable(L, 0, 2);
  9266. setField(L, "version", player->getProtocolVersion());
  9267. setField(L, "os", player->getOperatingSystem());
  9268. } else {
  9269. lua_pushnil(L);
  9270. }
  9271. return 1;
  9272. }
  9273.  
  9274. int LuaScriptInterface::luaPlayerGetHouse(lua_State* L)
  9275. {
  9276. // player:getHouse()
  9277. Player* player = getUserdata<Player>(L, 1);
  9278. if (!player) {
  9279. lua_pushnil(L);
  9280. return 1;
  9281. }
  9282.  
  9283. House* house = g_game.map.houses.getHouseByPlayerId(player->getGUID());
  9284. if (house) {
  9285. pushUserdata<House>(L, house);
  9286. setMetatable(L, -1, "House");
  9287. } else {
  9288. lua_pushnil(L);
  9289. }
  9290. return 1;
  9291. }
  9292.  
  9293. int LuaScriptInterface::luaPlayerSetGhostMode(lua_State* L)
  9294. {
  9295. // player:setGhostMode(enabled)
  9296. Player* player = getUserdata<Player>(L, 1);
  9297. if (!player) {
  9298. lua_pushnil(L);
  9299. return 1;
  9300. }
  9301.  
  9302. bool enabled = getBoolean(L, 2);
  9303. if (player->isInGhostMode() == enabled) {
  9304. pushBoolean(L, true);
  9305. return 1;
  9306. }
  9307.  
  9308. player->switchGhostMode();
  9309.  
  9310. Tile* tile = player->getTile();
  9311. const Position& position = player->getPosition();
  9312.  
  9313. SpectatorVec list;
  9314. g_game.map.getSpectators(list, position, true, true);
  9315. for (Creature* spectator : list) {
  9316. Player* tmpPlayer = spectator->getPlayer();
  9317. if (tmpPlayer != player && !tmpPlayer->isAccessPlayer()) {
  9318. if (enabled) {
  9319. tmpPlayer->sendRemoveTileThing(position, tile->getStackposOfCreature(tmpPlayer, player));
  9320. } else {
  9321. tmpPlayer->sendCreatureAppear(player, position, true);
  9322. }
  9323. } else {
  9324. tmpPlayer->sendCreatureChangeVisible(player, !enabled);
  9325. }
  9326. }
  9327.  
  9328. if (player->isInGhostMode()) {
  9329. for (const auto& it : g_game.getPlayers()) {
  9330. if (!it.second->isAccessPlayer()) {
  9331. it.second->notifyStatusChange(player, VIPSTATUS_OFFLINE);
  9332. }
  9333. }
  9334. IOLoginData::updateOnlineStatus(player->getGUID(), false);
  9335. } else {
  9336. for (const auto& it : g_game.getPlayers()) {
  9337. if (!it.second->isAccessPlayer()) {
  9338. it.second->notifyStatusChange(player, VIPSTATUS_ONLINE);
  9339. }
  9340. }
  9341. IOLoginData::updateOnlineStatus(player->getGUID(), true);
  9342. }
  9343. pushBoolean(L, true);
  9344. return 1;
  9345. }
  9346.  
  9347. int LuaScriptInterface::luaPlayerGetContainerId(lua_State* L)
  9348. {
  9349. // player:getContainerId(container)
  9350. Player* player = getUserdata<Player>(L, 1);
  9351. if (!player) {
  9352. lua_pushnil(L);
  9353. return 1;
  9354. }
  9355.  
  9356. Container* container = getUserdata<Container>(L, 2);
  9357. if (container) {
  9358. lua_pushnumber(L, player->getContainerID(container));
  9359. } else {
  9360. lua_pushnil(L);
  9361. }
  9362. return 1;
  9363. }
  9364.  
  9365. int LuaScriptInterface::luaPlayerGetContainerById(lua_State* L)
  9366. {
  9367. // player:getContainerById(id)
  9368. Player* player = getUserdata<Player>(L, 1);
  9369. if (!player) {
  9370. lua_pushnil(L);
  9371. return 1;
  9372. }
  9373.  
  9374. Container* container = player->getContainerByID(getNumber<uint8_t>(L, 2));
  9375. if (container) {
  9376. pushUserdata<Container>(L, container);
  9377. setMetatable(L, -1, "Container");
  9378. } else {
  9379. lua_pushnil(L);
  9380. }
  9381. return 1;
  9382. }
  9383.  
  9384. int LuaScriptInterface::luaPlayerGetContainerIndex(lua_State* L)
  9385. {
  9386. // player:getContainerIndex(id)
  9387. Player* player = getUserdata<Player>(L, 1);
  9388. if (player) {
  9389. lua_pushnumber(L, player->getContainerIndex(getNumber<uint8_t>(L, 2)));
  9390. } else {
  9391. lua_pushnil(L);
  9392. }
  9393. return 1;
  9394. }
  9395.  
  9396. int LuaScriptInterface::luaPlayerSendStoreError(lua_State* L)
  9397. {
  9398. // player::sendStoreError(errorType, message)
  9399. Player* player = getUserdata<Player>(L, 1);
  9400. if (player) {
  9401. StoreError_t errorType = static_cast<StoreError_t>(getNumber<uint8_t>(L, 2));
  9402. if (isString(L, 3)) {
  9403. player->sendStoreError(errorType, getString(L, 3));
  9404. pushBoolean(L, true);
  9405. return 1;
  9406. }
  9407. }
  9408.  
  9409. lua_pushnil(L);
  9410. return 1;
  9411. }
  9412.  
  9413. int32_t LuaScriptInterface::luaPlayerStartLiveCast(lua_State* L)
  9414. {
  9415. Player* player = getUserdata<Player>(L, 1);
  9416. if (!player) {
  9417. lua_pushnil(L);
  9418. return 1;
  9419. }
  9420.  
  9421. std::string password;
  9422. if (lua_gettop(L) == 2) {
  9423. password = getString(L, 2);
  9424. }
  9425.  
  9426. lua_pushboolean(L, player->startLiveCast(password));
  9427. return 1;
  9428. }
  9429.  
  9430. int32_t LuaScriptInterface::luaPlayerStopLiveCast(lua_State* L)
  9431. {
  9432. Player* player = getUserdata<Player>(L, 1);
  9433. if (!player) {
  9434. lua_pushnil(L);
  9435. return 1;
  9436. }
  9437.  
  9438. lua_pushboolean(L, player->stopLiveCast());
  9439. return 1;
  9440. }
  9441.  
  9442. int32_t LuaScriptInterface::luaPlayerIsLiveCaster(lua_State* L)
  9443. {
  9444. Player* player = getUserdata<Player>(L, 1);
  9445. if (!player) {
  9446. lua_pushnil(L);
  9447. return 1;
  9448. }
  9449.  
  9450. lua_pushboolean(L, player->isLiveCaster());
  9451. return 1;
  9452. }
  9453.  
  9454. int32_t LuaScriptInterface::luaPlayerGetSpectators(lua_State* L)
  9455. {
  9456. Player* player = getUserdata<Player>(L, 1);
  9457. if (!player || !player->isLiveCaster()) {
  9458. lua_pushnil(L);
  9459. return 1;
  9460. }
  9461.  
  9462. std::lock_guard<std::mutex> lock(player->client->liveCastLock);
  9463. std::vector<ProtocolSpectator_ptr> spectators;
  9464. player->getSpectators(spectators);
  9465.  
  9466. lua_createtable(L, spectators.size(), 0);
  9467.  
  9468. int idx = 0, anonymous = 0;
  9469. for (const auto spectator : spectators) {
  9470. std::string specName = spectator->getName();
  9471. if (specName.empty()) {
  9472. anonymous += 1;
  9473. } else {
  9474. pushString(L, specName);
  9475. lua_rawseti(L, -2, ++idx);
  9476. }
  9477. }
  9478.  
  9479. lua_pushnumber(L, anonymous);
  9480. return 2;
  9481. }
  9482.  
  9483. // Monster
  9484. int LuaScriptInterface::luaMonsterCreate(lua_State* L)
  9485. {
  9486. // Monster(id or userdata)
  9487. Monster* monster;
  9488. if (isNumber(L, 2)) {
  9489. monster = g_game.getMonsterByID(getNumber<uint32_t>(L, 2));
  9490. } else if (isUserdata(L, 2)) {
  9491. if (getUserdataType(L, 2) != LuaData_Monster) {
  9492. lua_pushnil(L);
  9493. return 1;
  9494. }
  9495. monster = getUserdata<Monster>(L, 2);
  9496. } else {
  9497. monster = nullptr;
  9498. }
  9499.  
  9500. if (monster) {
  9501. pushUserdata<Monster>(L, monster);
  9502. setMetatable(L, -1, "Monster");
  9503. } else {
  9504. lua_pushnil(L);
  9505. }
  9506. return 1;
  9507. }
  9508.  
  9509. int LuaScriptInterface::luaMonsterIsMonster(lua_State* L)
  9510. {
  9511. // monster:isMonster()
  9512. pushBoolean(L, getUserdata<const Monster>(L, 1) != nullptr);
  9513. return 1;
  9514. }
  9515.  
  9516. int LuaScriptInterface::luaMonsterGetType(lua_State* L)
  9517. {
  9518. // monster:getType()
  9519. const Monster* monster = getUserdata<const Monster>(L, 1);
  9520. if (monster) {
  9521. pushUserdata<MonsterType>(L, monster->mType);
  9522. setMetatable(L, -1, "MonsterType");
  9523. } else {
  9524. lua_pushnil(L);
  9525. }
  9526. return 1;
  9527. }
  9528.  
  9529. int LuaScriptInterface::luaMonsterGetSpawnPosition(lua_State* L)
  9530. {
  9531. // monster:getSpawnPosition()
  9532. const Monster* monster = getUserdata<const Monster>(L, 1);
  9533. if (monster) {
  9534. pushPosition(L, monster->getMasterPos());
  9535. } else {
  9536. lua_pushnil(L);
  9537. }
  9538. return 1;
  9539. }
  9540.  
  9541. int LuaScriptInterface::luaMonsterIsInSpawnRange(lua_State* L)
  9542. {
  9543. // monster:isInSpawnRange([position])
  9544. Monster* monster = getUserdata<Monster>(L, 1);
  9545. if (monster) {
  9546. pushBoolean(L, monster->isInSpawnRange(lua_gettop(L) >= 2 ? getPosition(L, 2) : monster->getPosition()));
  9547. } else {
  9548. lua_pushnil(L);
  9549. }
  9550. return 1;
  9551. }
  9552.  
  9553. int LuaScriptInterface::luaMonsterIsIdle(lua_State* L)
  9554. {
  9555. // monster:isIdle()
  9556. Monster* monster = getUserdata<Monster>(L, 1);
  9557. if (monster) {
  9558. pushBoolean(L, monster->getIdleStatus());
  9559. } else {
  9560. lua_pushnil(L);
  9561. }
  9562. return 1;
  9563. }
  9564.  
  9565. int LuaScriptInterface::luaMonsterSetIdle(lua_State* L)
  9566. {
  9567. // monster:setIdle(idle)
  9568. Monster* monster = getUserdata<Monster>(L, 1);
  9569. if (!monster) {
  9570. lua_pushnil(L);
  9571. return 1;
  9572. }
  9573.  
  9574. monster->setIdle(getBoolean(L, 2));
  9575. pushBoolean(L, true);
  9576. return 1;
  9577. }
  9578.  
  9579. int LuaScriptInterface::luaMonsterIsTarget(lua_State* L)
  9580. {
  9581. // monster:isTarget(creature)
  9582. Monster* monster = getUserdata<Monster>(L, 1);
  9583. if (monster) {
  9584. const Creature* creature = getCreature(L, 2);
  9585. pushBoolean(L, monster->isTarget(creature));
  9586. } else {
  9587. lua_pushnil(L);
  9588. }
  9589. return 1;
  9590. }
  9591.  
  9592. int LuaScriptInterface::luaMonsterIsOpponent(lua_State* L)
  9593. {
  9594. // monster:isOpponent(creature)
  9595. Monster* monster = getUserdata<Monster>(L, 1);
  9596. if (monster) {
  9597. const Creature* creature = getCreature(L, 2);
  9598. pushBoolean(L, monster->isOpponent(creature));
  9599. } else {
  9600. lua_pushnil(L);
  9601. }
  9602. return 1;
  9603. }
  9604.  
  9605. int LuaScriptInterface::luaMonsterIsFriend(lua_State* L)
  9606. {
  9607. // monster:isFriend(creature)
  9608. Monster* monster = getUserdata<Monster>(L, 1);
  9609. if (monster) {
  9610. const Creature* creature = getCreature(L, 2);
  9611. pushBoolean(L, monster->isFriend(creature));
  9612. } else {
  9613. lua_pushnil(L);
  9614. }
  9615. return 1;
  9616. }
  9617.  
  9618. int LuaScriptInterface::luaMonsterAddFriend(lua_State* L)
  9619. {
  9620. // monster:addFriend(creature)
  9621. Monster* monster = getUserdata<Monster>(L, 1);
  9622. if (monster) {
  9623. Creature* creature = getCreature(L, 2);
  9624. monster->addFriend(creature);
  9625. pushBoolean(L, true);
  9626. } else {
  9627. lua_pushnil(L);
  9628. }
  9629. return 1;
  9630. }
  9631.  
  9632. int LuaScriptInterface::luaMonsterRemoveFriend(lua_State* L)
  9633. {
  9634. // monster:removeFriend(creature)
  9635. Monster* monster = getUserdata<Monster>(L, 1);
  9636. if (monster) {
  9637. Creature* creature = getCreature(L, 2);
  9638. monster->removeFriend(creature);
  9639. pushBoolean(L, true);
  9640. } else {
  9641. lua_pushnil(L);
  9642. }
  9643. return 1;
  9644. }
  9645.  
  9646. int LuaScriptInterface::luaMonsterGetFriendList(lua_State* L)
  9647. {
  9648. // monster:getFriendList()
  9649. Monster* monster = getUserdata<Monster>(L, 1);
  9650. if (!monster) {
  9651. lua_pushnil(L);
  9652. return 1;
  9653. }
  9654.  
  9655. const auto& friendList = monster->getFriendList();
  9656. lua_createtable(L, friendList.size(), 0);
  9657.  
  9658. int index = 0;
  9659. for (Creature* creature : friendList) {
  9660. pushUserdata<Creature>(L, creature);
  9661. setCreatureMetatable(L, -1, creature);
  9662. lua_rawseti(L, -2, ++index);
  9663. }
  9664. return 1;
  9665. }
  9666.  
  9667. int LuaScriptInterface::luaMonsterGetFriendCount(lua_State* L)
  9668. {
  9669. // monster:getFriendCount()
  9670. Monster* monster = getUserdata<Monster>(L, 1);
  9671. if (monster) {
  9672. lua_pushnumber(L, monster->getFriendList().size());
  9673. } else {
  9674. lua_pushnil(L);
  9675. }
  9676. return 1;
  9677. }
  9678.  
  9679. int LuaScriptInterface::luaMonsterAddTarget(lua_State* L)
  9680. {
  9681. // monster:addTarget(creature[, pushFront = false])
  9682. Monster* monster = getUserdata<Monster>(L, 1);
  9683. if (!monster) {
  9684. lua_pushnil(L);
  9685. return 1;
  9686. }
  9687.  
  9688. Creature* creature = getCreature(L, 2);
  9689. bool pushFront = getBoolean(L, 3, false);
  9690. monster->addTarget(creature, pushFront);
  9691. pushBoolean(L, true);
  9692. return 1;
  9693. }
  9694.  
  9695. int LuaScriptInterface::luaMonsterRemoveTarget(lua_State* L)
  9696. {
  9697. // monster:removeTarget(creature)
  9698. Monster* monster = getUserdata<Monster>(L, 1);
  9699. if (!monster) {
  9700. lua_pushnil(L);
  9701. return 1;
  9702. }
  9703.  
  9704. monster->removeTarget(getCreature(L, 2));
  9705. pushBoolean(L, true);
  9706. return 1;
  9707. }
  9708.  
  9709. int LuaScriptInterface::luaMonsterGetTargetList(lua_State* L)
  9710. {
  9711. // monster:getTargetList()
  9712. Monster* monster = getUserdata<Monster>(L, 1);
  9713. if (!monster) {
  9714. lua_pushnil(L);
  9715. return 1;
  9716. }
  9717.  
  9718. const auto& targetList = monster->getTargetList();
  9719. lua_createtable(L, targetList.size(), 0);
  9720.  
  9721. int index = 0;
  9722. for (Creature* creature : targetList) {
  9723. pushUserdata<Creature>(L, creature);
  9724. setCreatureMetatable(L, -1, creature);
  9725. lua_rawseti(L, -2, ++index);
  9726. }
  9727. return 1;
  9728. }
  9729.  
  9730. int LuaScriptInterface::luaMonsterGetTargetCount(lua_State* L)
  9731. {
  9732. // monster:getTargetCount()
  9733. Monster* monster = getUserdata<Monster>(L, 1);
  9734. if (monster) {
  9735. lua_pushnumber(L, monster->getTargetList().size());
  9736. } else {
  9737. lua_pushnil(L);
  9738. }
  9739. return 1;
  9740. }
  9741.  
  9742. int LuaScriptInterface::luaMonsterSelectTarget(lua_State* L)
  9743. {
  9744. // monster:selectTarget(creature)
  9745. Monster* monster = getUserdata<Monster>(L, 1);
  9746. if (monster) {
  9747. Creature* creature = getCreature(L, 2);
  9748. pushBoolean(L, monster->selectTarget(creature));
  9749. } else {
  9750. lua_pushnil(L);
  9751. }
  9752. return 1;
  9753. }
  9754.  
  9755. int LuaScriptInterface::luaMonsterSearchTarget(lua_State* L)
  9756. {
  9757. // monster:searchTarget([searchType = TARGETSEARCH_DEFAULT])
  9758. Monster* monster = getUserdata<Monster>(L, 1);
  9759. if (monster) {
  9760. TargetSearchType_t searchType = getNumber<TargetSearchType_t>(L, 2, TARGETSEARCH_DEFAULT);
  9761. pushBoolean(L, monster->searchTarget(searchType));
  9762. } else {
  9763. lua_pushnil(L);
  9764. }
  9765. return 1;
  9766. }
  9767.  
  9768. // Npc
  9769. int LuaScriptInterface::luaNpcCreate(lua_State* L)
  9770. {
  9771. // Npc([id or name or userdata])
  9772. Npc* npc;
  9773. if (lua_gettop(L) >= 2) {
  9774. if (isNumber(L, 2)) {
  9775. npc = g_game.getNpcByID(getNumber<uint32_t>(L, 2));
  9776. } else if (isString(L, 2)) {
  9777. npc = g_game.getNpcByName(getString(L, 2));
  9778. } else if (isUserdata(L, 2)) {
  9779. if (getUserdataType(L, 2) != LuaData_Npc) {
  9780. lua_pushnil(L);
  9781. return 1;
  9782. }
  9783. npc = getUserdata<Npc>(L, 2);
  9784. } else {
  9785. npc = nullptr;
  9786. }
  9787. } else {
  9788. npc = getScriptEnv()->getNpc();
  9789. }
  9790.  
  9791. if (npc) {
  9792. pushUserdata<Npc>(L, npc);
  9793. setMetatable(L, -1, "Npc");
  9794. } else {
  9795. lua_pushnil(L);
  9796. }
  9797. return 1;
  9798. }
  9799.  
  9800. int LuaScriptInterface::luaNpcIsNpc(lua_State* L)
  9801. {
  9802. // npc:isNpc()
  9803. pushBoolean(L, getUserdata<const Npc>(L, 1) != nullptr);
  9804. return 1;
  9805. }
  9806.  
  9807. int LuaScriptInterface::luaNpcSetMasterPos(lua_State* L)
  9808. {
  9809. // npc:setMasterPos(pos[, radius])
  9810. Npc* npc = getUserdata<Npc>(L, 1);
  9811. if (!npc) {
  9812. lua_pushnil(L);
  9813. return 1;
  9814. }
  9815.  
  9816. const Position& pos = getPosition(L, 2);
  9817. int32_t radius = getNumber<int32_t>(L, 3, 1);
  9818. npc->setMasterPos(pos, radius);
  9819. pushBoolean(L, true);
  9820. return 1;
  9821. }
  9822.  
  9823. int LuaScriptInterface::luaNpcGetSpeechBubble(lua_State* L)
  9824. {
  9825. // npc:getSpeechBubble()
  9826. Npc* npc = getUserdata<Npc>(L, 1);
  9827. if (npc) {
  9828. lua_pushnumber(L, npc->getSpeechBubble());
  9829. } else {
  9830. lua_pushnil(L);
  9831. }
  9832. return 1;
  9833. }
  9834.  
  9835. int LuaScriptInterface::luaNpcSetSpeechBubble(lua_State* L)
  9836. {
  9837. // npc:setSpeechBubble(speechBubble)
  9838. Npc* npc = getUserdata<Npc>(L, 1);
  9839. if (npc) {
  9840. npc->setSpeechBubble(getNumber<uint8_t>(L, 2));
  9841. }
  9842. return 0;
  9843. }
  9844.  
  9845. // Guild
  9846. int LuaScriptInterface::luaGuildCreate(lua_State* L)
  9847. {
  9848. // Guild(id)
  9849. uint32_t id = getNumber<uint32_t>(L, 2);
  9850.  
  9851. Guild* guild = g_game.getGuild(id);
  9852. if (guild) {
  9853. pushUserdata<Guild>(L, guild);
  9854. setMetatable(L, -1, "Guild");
  9855. } else {
  9856. lua_pushnil(L);
  9857. }
  9858. return 1;
  9859. }
  9860.  
  9861. int LuaScriptInterface::luaGuildGetId(lua_State* L)
  9862. {
  9863. // guild:getId()
  9864. Guild* guild = getUserdata<Guild>(L, 1);
  9865. if (guild) {
  9866. lua_pushnumber(L, guild->getId());
  9867. } else {
  9868. lua_pushnil(L);
  9869. }
  9870. return 1;
  9871. }
  9872.  
  9873. int LuaScriptInterface::luaGuildGetName(lua_State* L)
  9874. {
  9875. // guild:getName()
  9876. Guild* guild = getUserdata<Guild>(L, 1);
  9877. if (guild) {
  9878. pushString(L, guild->getName());
  9879. } else {
  9880. lua_pushnil(L);
  9881. }
  9882. return 1;
  9883. }
  9884.  
  9885. int LuaScriptInterface::luaGuildGetMembersOnline(lua_State* L)
  9886. {
  9887. // guild:getMembersOnline()
  9888. const Guild* guild = getUserdata<const Guild>(L, 1);
  9889. if (!guild) {
  9890. lua_pushnil(L);
  9891. return 1;
  9892. }
  9893.  
  9894. const auto& members = guild->getMembersOnline();
  9895. lua_createtable(L, members.size(), 0);
  9896.  
  9897. int index = 0;
  9898. for (Player* player : members) {
  9899. pushUserdata<Player>(L, player);
  9900. setMetatable(L, -1, "Player");
  9901. lua_rawseti(L, -2, ++index);
  9902. }
  9903. return 1;
  9904. }
  9905.  
  9906. int LuaScriptInterface::luaGuildGetBankBalance(lua_State* L)
  9907. {
  9908. // guild:getBankBalance()
  9909. Guild* guild = getUserdata<Guild>(L, 1);
  9910. if (!guild) {
  9911. lua_pushnil(L);
  9912. return 1;
  9913. }
  9914.  
  9915. lua_pushnumber(L, guild->getBankBalance());
  9916. return 1;
  9917. }
  9918.  
  9919. int LuaScriptInterface::luaGuildSetBankBalance(lua_State* L)
  9920. {
  9921. // guild:setBankBalance(balance)
  9922. Guild* guild = getUserdata<Guild>(L, 1);
  9923. if (!guild) {
  9924. lua_pushnil(L);
  9925. return 1;
  9926. }
  9927.  
  9928. auto balance = getNumber<uint32_t>(L, 2);
  9929. guild->setBankBalance(balance);
  9930. pushBoolean(L, true);
  9931. return 1;
  9932. }
  9933.  
  9934. int LuaScriptInterface::luaGuildAddRank(lua_State* L)
  9935. {
  9936. // guild:addRank(id, name, level)
  9937. Guild* guild = getUserdata<Guild>(L, 1);
  9938. if (guild) {
  9939. uint32_t id = getNumber<uint32_t>(L, 2);
  9940. const std::string& name = getString(L, 3);
  9941. uint8_t level = getNumber<uint8_t>(L, 4);
  9942. guild->addRank(id, name, level);
  9943. pushBoolean(L, true);
  9944. } else {
  9945. lua_pushnil(L);
  9946. }
  9947. return 1;
  9948. }
  9949.  
  9950. int LuaScriptInterface::luaGuildGetRankById(lua_State* L)
  9951. {
  9952. // guild:getRankById(id)
  9953. Guild* guild = getUserdata<Guild>(L, 1);
  9954. if (!guild) {
  9955. lua_pushnil(L);
  9956. return 1;
  9957. }
  9958.  
  9959. uint32_t id = getNumber<uint32_t>(L, 2);
  9960. GuildRank* rank = guild->getRankById(id);
  9961. if (rank) {
  9962. lua_createtable(L, 0, 3);
  9963. setField(L, "id", rank->id);
  9964. setField(L, "name", rank->name);
  9965. setField(L, "level", rank->level);
  9966. } else {
  9967. lua_pushnil(L);
  9968. }
  9969. return 1;
  9970. }
  9971.  
  9972. int LuaScriptInterface::luaGuildGetRankByLevel(lua_State* L)
  9973. {
  9974. // guild:getRankByLevel(level)
  9975. const Guild* guild = getUserdata<const Guild>(L, 1);
  9976. if (!guild) {
  9977. lua_pushnil(L);
  9978. return 1;
  9979. }
  9980.  
  9981. uint8_t level = getNumber<uint8_t>(L, 2);
  9982. const GuildRank* rank = guild->getRankByLevel(level);
  9983. if (rank) {
  9984. lua_createtable(L, 0, 3);
  9985. setField(L, "id", rank->id);
  9986. setField(L, "name", rank->name);
  9987. setField(L, "level", rank->level);
  9988. } else {
  9989. lua_pushnil(L);
  9990. }
  9991. return 1;
  9992. }
  9993.  
  9994. int LuaScriptInterface::luaGuildGetMotd(lua_State* L)
  9995. {
  9996. // guild:getMotd()
  9997. Guild* guild = getUserdata<Guild>(L, 1);
  9998. if (guild) {
  9999. pushString(L, guild->getMotd());
  10000. } else {
  10001. lua_pushnil(L);
  10002. }
  10003. return 1;
  10004. }
  10005.  
  10006. int LuaScriptInterface::luaGuildSetMotd(lua_State* L)
  10007. {
  10008. // guild:setMotd(motd)
  10009. const std::string& motd = getString(L, 2);
  10010. Guild* guild = getUserdata<Guild>(L, 1);
  10011. if (guild) {
  10012. guild->setMotd(motd);
  10013. pushBoolean(L, true);
  10014. } else {
  10015. lua_pushnil(L);
  10016. }
  10017. return 1;
  10018. }
  10019.  
  10020. // Group
  10021. int LuaScriptInterface::luaGroupCreate(lua_State* L)
  10022. {
  10023. // Group(id)
  10024. uint32_t id = getNumber<uint32_t>(L, 2);
  10025.  
  10026. Group* group = g_game.groups.getGroup(id);
  10027. if (group) {
  10028. pushUserdata<Group>(L, group);
  10029. setMetatable(L, -1, "Group");
  10030. } else {
  10031. lua_pushnil(L);
  10032. }
  10033. return 1;
  10034. }
  10035.  
  10036. int LuaScriptInterface::luaGroupGetId(lua_State* L)
  10037. {
  10038. // group:getId()
  10039. Group* group = getUserdata<Group>(L, 1);
  10040. if (group) {
  10041. lua_pushnumber(L, group->id);
  10042. } else {
  10043. lua_pushnil(L);
  10044. }
  10045. return 1;
  10046. }
  10047.  
  10048. int LuaScriptInterface::luaGroupGetName(lua_State* L)
  10049. {
  10050. // group:getName()
  10051. Group* group = getUserdata<Group>(L, 1);
  10052. if (group) {
  10053. pushString(L, group->name);
  10054. } else {
  10055. lua_pushnil(L);
  10056. }
  10057. return 1;
  10058. }
  10059.  
  10060. int LuaScriptInterface::luaGroupGetFlags(lua_State* L)
  10061. {
  10062. // group:getFlags()
  10063. Group* group = getUserdata<Group>(L, 1);
  10064. if (group) {
  10065. lua_pushnumber(L, group->flags);
  10066. } else {
  10067. lua_pushnil(L);
  10068. }
  10069. return 1;
  10070. }
  10071.  
  10072. int LuaScriptInterface::luaGroupGetAccess(lua_State* L)
  10073. {
  10074. // group:getAccess()
  10075. Group* group = getUserdata<Group>(L, 1);
  10076. if (group) {
  10077. pushBoolean(L, group->access);
  10078. } else {
  10079. lua_pushnil(L);
  10080. }
  10081. return 1;
  10082. }
  10083.  
  10084. int LuaScriptInterface::luaGroupGetMaxDepotItems(lua_State* L)
  10085. {
  10086. // group:getMaxDepotItems()
  10087. Group* group = getUserdata<Group>(L, 1);
  10088. if (group) {
  10089. lua_pushnumber(L, group->maxDepotItems);
  10090. } else {
  10091. lua_pushnil(L);
  10092. }
  10093. return 1;
  10094. }
  10095.  
  10096. int LuaScriptInterface::luaGroupGetMaxVipEntries(lua_State* L)
  10097. {
  10098. // group:getMaxVipEntries()
  10099. Group* group = getUserdata<Group>(L, 1);
  10100. if (group) {
  10101. lua_pushnumber(L, group->maxVipEntries);
  10102. } else {
  10103. lua_pushnil(L);
  10104. }
  10105. return 1;
  10106. }
  10107.  
  10108. // Vocation
  10109. int LuaScriptInterface::luaVocationCreate(lua_State* L)
  10110. {
  10111. // Vocation(id or name)
  10112. uint32_t id;
  10113. if (isNumber(L, 2)) {
  10114. id = getNumber<uint32_t>(L, 2);
  10115. } else {
  10116. id = g_vocations.getVocationId(getString(L, 2));
  10117. }
  10118.  
  10119. Vocation* vocation = g_vocations.getVocation(id);
  10120. if (vocation) {
  10121. pushUserdata<Vocation>(L, vocation);
  10122. setMetatable(L, -1, "Vocation");
  10123. } else {
  10124. lua_pushnil(L);
  10125. }
  10126. return 1;
  10127. }
  10128.  
  10129. int LuaScriptInterface::luaVocationGetId(lua_State* L)
  10130. {
  10131. // vocation:getId()
  10132. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10133. if (vocation) {
  10134. lua_pushnumber(L, vocation->getId());
  10135. } else {
  10136. lua_pushnil(L);
  10137. }
  10138. return 1;
  10139. }
  10140.  
  10141. int LuaScriptInterface::luaVocationGetClientId(lua_State* L)
  10142. {
  10143. // vocation:getClientId()
  10144. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10145. if (vocation) {
  10146. lua_pushnumber(L, vocation->getClientId());
  10147. } else {
  10148. lua_pushnil(L);
  10149. }
  10150. return 1;
  10151. }
  10152.  
  10153. int LuaScriptInterface::luaVocationGetName(lua_State* L)
  10154. {
  10155. // vocation:getName()
  10156. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10157. if (vocation) {
  10158. pushString(L, vocation->getVocName());
  10159. } else {
  10160. lua_pushnil(L);
  10161. }
  10162. return 1;
  10163. }
  10164.  
  10165. int LuaScriptInterface::luaVocationGetDescription(lua_State* L)
  10166. {
  10167. // vocation:getDescription()
  10168. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10169. if (vocation) {
  10170. pushString(L, vocation->getVocDescription());
  10171. } else {
  10172. lua_pushnil(L);
  10173. }
  10174. return 1;
  10175. }
  10176.  
  10177. int LuaScriptInterface::luaVocationGetRequiredSkillTries(lua_State* L)
  10178. {
  10179. // vocation:getRequiredSkillTries(skillType, skillLevel)
  10180. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10181. if (vocation) {
  10182. skills_t skillType = getNumber<skills_t>(L, 2);
  10183. uint16_t skillLevel = getNumber<uint16_t>(L, 3);
  10184. lua_pushnumber(L, vocation->getReqSkillTries(skillType, skillLevel));
  10185. } else {
  10186. lua_pushnil(L);
  10187. }
  10188. return 1;
  10189. }
  10190.  
  10191. int LuaScriptInterface::luaVocationGetRequiredManaSpent(lua_State* L)
  10192. {
  10193. // vocation:getRequiredManaSpent(magicLevel)
  10194. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10195. if (vocation) {
  10196. uint32_t magicLevel = getNumber<uint32_t>(L, 2);
  10197. lua_pushnumber(L, vocation->getReqMana(magicLevel));
  10198. } else {
  10199. lua_pushnil(L);
  10200. }
  10201. return 1;
  10202. }
  10203.  
  10204. int LuaScriptInterface::luaVocationGetCapacityGain(lua_State* L)
  10205. {
  10206. // vocation:getCapacityGain()
  10207. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10208. if (vocation) {
  10209. lua_pushnumber(L, vocation->getCapGain());
  10210. } else {
  10211. lua_pushnil(L);
  10212. }
  10213. return 1;
  10214. }
  10215.  
  10216. int LuaScriptInterface::luaVocationGetHealthGain(lua_State* L)
  10217. {
  10218. // vocation:getHealthGain()
  10219. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10220. if (vocation) {
  10221. lua_pushnumber(L, vocation->getHPGain());
  10222. } else {
  10223. lua_pushnil(L);
  10224. }
  10225. return 1;
  10226. }
  10227.  
  10228. int LuaScriptInterface::luaVocationGetHealthGainTicks(lua_State* L)
  10229. {
  10230. // vocation:getHealthGainTicks()
  10231. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10232. if (vocation) {
  10233. lua_pushnumber(L, vocation->getHealthGainTicks());
  10234. } else {
  10235. lua_pushnil(L);
  10236. }
  10237. return 1;
  10238. }
  10239.  
  10240. int LuaScriptInterface::luaVocationGetHealthGainAmount(lua_State* L)
  10241. {
  10242. // vocation:getHealthGainAmount()
  10243. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10244. if (vocation) {
  10245. lua_pushnumber(L, vocation->getHealthGainAmount());
  10246. } else {
  10247. lua_pushnil(L);
  10248. }
  10249. return 1;
  10250. }
  10251.  
  10252. int LuaScriptInterface::luaVocationGetManaGain(lua_State* L)
  10253. {
  10254. // vocation:getManaGain()
  10255. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10256. if (vocation) {
  10257. lua_pushnumber(L, vocation->getManaGain());
  10258. } else {
  10259. lua_pushnil(L);
  10260. }
  10261. return 1;
  10262. }
  10263.  
  10264. int LuaScriptInterface::luaVocationGetManaGainTicks(lua_State* L)
  10265. {
  10266. // vocation:getManaGainTicks()
  10267. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10268. if (vocation) {
  10269. lua_pushnumber(L, vocation->getManaGainTicks());
  10270. } else {
  10271. lua_pushnil(L);
  10272. }
  10273. return 1;
  10274. }
  10275.  
  10276. int LuaScriptInterface::luaVocationGetManaGainAmount(lua_State* L)
  10277. {
  10278. // vocation:getManaGainAmount()
  10279. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10280. if (vocation) {
  10281. lua_pushnumber(L, vocation->getManaGainAmount());
  10282. } else {
  10283. lua_pushnil(L);
  10284. }
  10285. return 1;
  10286. }
  10287.  
  10288. int LuaScriptInterface::luaVocationGetMaxSoul(lua_State* L)
  10289. {
  10290. // vocation:getMaxSoul()
  10291. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10292. if (vocation) {
  10293. lua_pushnumber(L, vocation->getSoulMax());
  10294. } else {
  10295. lua_pushnil(L);
  10296. }
  10297. return 1;
  10298. }
  10299.  
  10300. int LuaScriptInterface::luaVocationGetSoulGainTicks(lua_State* L)
  10301. {
  10302. // vocation:getSoulGainTicks()
  10303. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10304. if (vocation) {
  10305. lua_pushnumber(L, vocation->getSoulGainTicks());
  10306. } else {
  10307. lua_pushnil(L);
  10308. }
  10309. return 1;
  10310. }
  10311.  
  10312. int LuaScriptInterface::luaVocationGetAttackSpeed(lua_State* L)
  10313. {
  10314. // vocation:getAttackSpeed()
  10315. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10316. if (vocation) {
  10317. lua_pushnumber(L, vocation->getAttackSpeed());
  10318. } else {
  10319. lua_pushnil(L);
  10320. }
  10321. return 1;
  10322. }
  10323.  
  10324. int LuaScriptInterface::luaVocationGetBaseSpeed(lua_State* L)
  10325. {
  10326. // vocation:getBaseSpeed()
  10327. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10328. if (vocation) {
  10329. lua_pushnumber(L, vocation->getBaseSpeed());
  10330. } else {
  10331. lua_pushnil(L);
  10332. }
  10333. return 1;
  10334. }
  10335.  
  10336. int LuaScriptInterface::luaVocationGetDemotion(lua_State* L)
  10337. {
  10338. // vocation:getDemotion()
  10339. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10340. if (!vocation) {
  10341. lua_pushnil(L);
  10342. return 1;
  10343. }
  10344.  
  10345. uint16_t fromId = vocation->getFromVocation();
  10346. if (fromId == VOCATION_NONE) {
  10347. lua_pushnil(L);
  10348. return 1;
  10349. }
  10350.  
  10351. Vocation* demotedVocation = g_vocations.getVocation(fromId);
  10352. if (demotedVocation && demotedVocation != vocation) {
  10353. pushUserdata<Vocation>(L, demotedVocation);
  10354. setMetatable(L, -1, "Vocation");
  10355. } else {
  10356. lua_pushnil(L);
  10357. }
  10358. return 1;
  10359. }
  10360.  
  10361. int LuaScriptInterface::luaVocationGetPromotion(lua_State* L)
  10362. {
  10363. // vocation:getPromotion()
  10364. Vocation* vocation = getUserdata<Vocation>(L, 1);
  10365. if (!vocation) {
  10366. lua_pushnil(L);
  10367. return 1;
  10368. }
  10369.  
  10370. uint16_t promotedId = g_vocations.getPromotedVocation(vocation->getId());
  10371. if (promotedId == VOCATION_NONE) {
  10372. lua_pushnil(L);
  10373. return 1;
  10374. }
  10375.  
  10376. Vocation* promotedVocation = g_vocations.getVocation(promotedId);
  10377. if (promotedVocation && promotedVocation != vocation) {
  10378. pushUserdata<Vocation>(L, promotedVocation);
  10379. setMetatable(L, -1, "Vocation");
  10380. } else {
  10381. lua_pushnil(L);
  10382. }
  10383. return 1;
  10384. }
  10385.  
  10386. // Town
  10387. int LuaScriptInterface::luaTownCreate(lua_State* L)
  10388. {
  10389. // Town(id or name)
  10390. Town* town;
  10391. if (isNumber(L, 2)) {
  10392. town = g_game.map.towns.getTown(getNumber<uint32_t>(L, 2));
  10393. } else if (isString(L, 2)) {
  10394. town = g_game.map.towns.getTown(getString(L, 2));
  10395. } else {
  10396. town = nullptr;
  10397. }
  10398.  
  10399. if (town) {
  10400. pushUserdata<Town>(L, town);
  10401. setMetatable(L, -1, "Town");
  10402. } else {
  10403. lua_pushnil(L);
  10404. }
  10405. return 1;
  10406. }
  10407.  
  10408. int LuaScriptInterface::luaTownGetId(lua_State* L)
  10409. {
  10410. // town:getId()
  10411. Town* town = getUserdata<Town>(L, 1);
  10412. if (town) {
  10413. lua_pushnumber(L, town->getID());
  10414. } else {
  10415. lua_pushnil(L);
  10416. }
  10417. return 1;
  10418. }
  10419.  
  10420. int LuaScriptInterface::luaTownGetName(lua_State* L)
  10421. {
  10422. // town:getName()
  10423. Town* town = getUserdata<Town>(L, 1);
  10424. if (town) {
  10425. pushString(L, town->getName());
  10426. } else {
  10427. lua_pushnil(L);
  10428. }
  10429. return 1;
  10430. }
  10431.  
  10432. int LuaScriptInterface::luaTownGetTemplePosition(lua_State* L)
  10433. {
  10434. // town:getTemplePosition()
  10435. Town* town = getUserdata<Town>(L, 1);
  10436. if (town) {
  10437. pushPosition(L, town->getTemplePosition());
  10438. } else {
  10439. lua_pushnil(L);
  10440. }
  10441. return 1;
  10442. }
  10443.  
  10444. // House
  10445. int LuaScriptInterface::luaHouseCreate(lua_State* L)
  10446. {
  10447. // House(id)
  10448. House* house = g_game.map.houses.getHouse(getNumber<uint32_t>(L, 2));
  10449. if (house) {
  10450. pushUserdata<House>(L, house);
  10451. setMetatable(L, -1, "House");
  10452. } else {
  10453. lua_pushnil(L);
  10454. }
  10455. return 1;
  10456. }
  10457.  
  10458. int LuaScriptInterface::luaHouseGetId(lua_State* L)
  10459. {
  10460. // house:getId()
  10461. House* house = getUserdata<House>(L, 1);
  10462. if (house) {
  10463. lua_pushnumber(L, house->getId());
  10464. } else {
  10465. lua_pushnil(L);
  10466. }
  10467. return 1;
  10468. }
  10469.  
  10470. int LuaScriptInterface::luaHouseGetName(lua_State* L)
  10471. {
  10472. // house:getName()
  10473. House* house = getUserdata<House>(L, 1);
  10474. if (house) {
  10475. pushString(L, house->getName());
  10476. } else {
  10477. lua_pushnil(L);
  10478. }
  10479. return 1;
  10480. }
  10481.  
  10482. int LuaScriptInterface::luaHouseGetTown(lua_State* L)
  10483. {
  10484. // house:getTown()
  10485. House* house = getUserdata<House>(L, 1);
  10486. if (!house) {
  10487. lua_pushnil(L);
  10488. return 1;
  10489. }
  10490.  
  10491. Town* town = g_game.map.towns.getTown(house->getTownId());
  10492. if (town) {
  10493. pushUserdata<Town>(L, town);
  10494. setMetatable(L, -1, "Town");
  10495. } else {
  10496. lua_pushnil(L);
  10497. }
  10498. return 1;
  10499. }
  10500.  
  10501. int LuaScriptInterface::luaHouseGetExitPosition(lua_State* L)
  10502. {
  10503. // house:getExitPosition()
  10504. House* house = getUserdata<House>(L, 1);
  10505. if (house) {
  10506. pushPosition(L, house->getEntryPosition());
  10507. } else {
  10508. lua_pushnil(L);
  10509. }
  10510. return 1;
  10511. }
  10512.  
  10513. int LuaScriptInterface::luaHouseGetRent(lua_State* L)
  10514. {
  10515. // house:getRent()
  10516. House* house = getUserdata<House>(L, 1);
  10517. if (house) {
  10518. lua_pushnumber(L, house->getRent());
  10519. } else {
  10520. lua_pushnil(L);
  10521. }
  10522. return 1;
  10523. }
  10524.  
  10525. int LuaScriptInterface::luaHouseGetOwnerGuid(lua_State* L)
  10526. {
  10527. // house:getOwnerGuid()
  10528. House* house = getUserdata<House>(L, 1);
  10529. if (house) {
  10530. lua_pushnumber(L, house->getOwner());
  10531. } else {
  10532. lua_pushnil(L);
  10533. }
  10534. return 1;
  10535. }
  10536.  
  10537. int LuaScriptInterface::luaHouseSetOwnerGuid(lua_State* L)
  10538. {
  10539. // house:setOwnerGuid(guid[, updateDatabase = true])
  10540. House* house = getUserdata<House>(L, 1);
  10541. if (house) {
  10542. uint32_t guid = getNumber<uint32_t>(L, 2);
  10543. bool updateDatabase = getBoolean(L, 3, true);
  10544. house->setOwner(guid, updateDatabase);
  10545. pushBoolean(L, true);
  10546. } else {
  10547. lua_pushnil(L);
  10548. }
  10549. return 1;
  10550. }
  10551.  
  10552. int LuaScriptInterface::luaHouseGetBeds(lua_State* L)
  10553. {
  10554. // house:getBeds()
  10555. House* house = getUserdata<House>(L, 1);
  10556. if (!house) {
  10557. lua_pushnil(L);
  10558. return 1;
  10559. }
  10560.  
  10561. const auto& beds = house->getBeds();
  10562. lua_createtable(L, beds.size(), 0);
  10563.  
  10564. int index = 0;
  10565. for (BedItem* bedItem : beds) {
  10566. pushUserdata<Item>(L, bedItem);
  10567. setItemMetatable(L, -1, bedItem);
  10568. lua_rawseti(L, -2, ++index);
  10569. }
  10570. return 1;
  10571. }
  10572.  
  10573. int LuaScriptInterface::luaHouseGetBedCount(lua_State* L)
  10574. {
  10575. // house:getBedCount()
  10576. House* house = getUserdata<House>(L, 1);
  10577. if (house) {
  10578. lua_pushnumber(L, house->getBedCount());
  10579. } else {
  10580. lua_pushnil(L);
  10581. }
  10582. return 1;
  10583. }
  10584.  
  10585. int LuaScriptInterface::luaHouseGetDoors(lua_State* L)
  10586. {
  10587. // house:getDoors()
  10588. House* house = getUserdata<House>(L, 1);
  10589. if (!house) {
  10590. lua_pushnil(L);
  10591. return 1;
  10592. }
  10593.  
  10594. const auto& doors = house->getDoors();
  10595. lua_createtable(L, doors.size(), 0);
  10596.  
  10597. int index = 0;
  10598. for (Door* door : doors) {
  10599. pushUserdata<Item>(L, door);
  10600. setItemMetatable(L, -1, door);
  10601. lua_rawseti(L, -2, ++index);
  10602. }
  10603. return 1;
  10604. }
  10605.  
  10606. int LuaScriptInterface::luaHouseGetDoorCount(lua_State* L)
  10607. {
  10608. // house:getDoorCount()
  10609. House* house = getUserdata<House>(L, 1);
  10610. if (house) {
  10611. lua_pushnumber(L, house->getDoors().size());
  10612. } else {
  10613. lua_pushnil(L);
  10614. }
  10615. return 1;
  10616. }
  10617.  
  10618. int LuaScriptInterface::luaHouseGetTiles(lua_State* L)
  10619. {
  10620. // house:getTiles()
  10621. House* house = getUserdata<House>(L, 1);
  10622. if (!house) {
  10623. lua_pushnil(L);
  10624. return 1;
  10625. }
  10626.  
  10627. const auto& tiles = house->getTiles();
  10628. lua_createtable(L, tiles.size(), 0);
  10629.  
  10630. int index = 0;
  10631. for (Tile* tile : tiles) {
  10632. pushUserdata<Tile>(L, tile);
  10633. setMetatable(L, -1, "Tile");
  10634. lua_rawseti(L, -2, ++index);
  10635. }
  10636. return 1;
  10637. }
  10638.  
  10639. int LuaScriptInterface::luaHouseGetTileCount(lua_State* L)
  10640. {
  10641. // house:getTileCount()
  10642. House* house = getUserdata<House>(L, 1);
  10643. if (house) {
  10644. lua_pushnumber(L, house->getTiles().size());
  10645. } else {
  10646. lua_pushnil(L);
  10647. }
  10648. return 1;
  10649. }
  10650.  
  10651. int LuaScriptInterface::luaHouseGetAccessList(lua_State* L)
  10652. {
  10653. // house:getAccessList(listId)
  10654. House* house = getUserdata<House>(L, 1);
  10655. if (!house) {
  10656. lua_pushnil(L);
  10657. return 1;
  10658. }
  10659.  
  10660. std::string list;
  10661. uint32_t listId = getNumber<uint32_t>(L, 2);
  10662. if (house->getAccessList(listId, list)) {
  10663. pushString(L, list);
  10664. } else {
  10665. pushBoolean(L, false);
  10666. }
  10667. return 1;
  10668. }
  10669.  
  10670. int LuaScriptInterface::luaHouseSetAccessList(lua_State* L)
  10671. {
  10672. // house:setAccessList(listId, list)
  10673. House* house = getUserdata<House>(L, 1);
  10674. if (!house) {
  10675. lua_pushnil(L);
  10676. return 1;
  10677. }
  10678.  
  10679. uint32_t listId = getNumber<uint32_t>(L, 2);
  10680. const std::string& list = getString(L, 3);
  10681. house->setAccessList(listId, list);
  10682. pushBoolean(L, true);
  10683. return 1;
  10684. }
  10685.  
  10686. // ItemType
  10687. int LuaScriptInterface::luaItemTypeCreate(lua_State* L)
  10688. {
  10689. // ItemType(id or name)
  10690. uint32_t id;
  10691. if (isNumber(L, 2)) {
  10692. id = getNumber<uint32_t>(L, 2);
  10693. } else {
  10694. id = Item::items.getItemIdByName(getString(L, 2));
  10695. }
  10696.  
  10697. const ItemType& itemType = Item::items[id];
  10698. pushUserdata<const ItemType>(L, &itemType);
  10699. setMetatable(L, -1, "ItemType");
  10700. return 1;
  10701. }
  10702.  
  10703. int LuaScriptInterface::luaItemTypeIsCorpse(lua_State* L)
  10704. {
  10705. // itemType:isCorpse()
  10706. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10707. if (itemType) {
  10708. pushBoolean(L, itemType->corpseType != RACE_NONE);
  10709. } else {
  10710. lua_pushnil(L);
  10711. }
  10712. return 1;
  10713. }
  10714.  
  10715. int LuaScriptInterface::luaItemTypeIsDoor(lua_State* L)
  10716. {
  10717. // itemType:isDoor()
  10718. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10719. if (itemType) {
  10720. pushBoolean(L, itemType->isDoor());
  10721. } else {
  10722. lua_pushnil(L);
  10723. }
  10724. return 1;
  10725. }
  10726.  
  10727. int LuaScriptInterface::luaItemTypeIsContainer(lua_State* L)
  10728. {
  10729. // itemType:isContainer()
  10730. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10731. if (itemType) {
  10732. pushBoolean(L, itemType->isContainer());
  10733. } else {
  10734. lua_pushnil(L);
  10735. }
  10736. return 1;
  10737. }
  10738.  
  10739. int LuaScriptInterface::luaItemTypeIsFluidContainer(lua_State* L)
  10740. {
  10741. // itemType:isFluidContainer()
  10742. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10743. if (itemType) {
  10744. pushBoolean(L, itemType->isFluidContainer());
  10745. } else {
  10746. lua_pushnil(L);
  10747. }
  10748. return 1;
  10749. }
  10750.  
  10751. int LuaScriptInterface::luaItemTypeIsMovable(lua_State* L)
  10752. {
  10753. // itemType:isMovable()
  10754. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10755. if (itemType) {
  10756. pushBoolean(L, itemType->moveable);
  10757. } else {
  10758. lua_pushnil(L);
  10759. }
  10760. return 1;
  10761. }
  10762.  
  10763. int LuaScriptInterface::luaItemTypeIsRune(lua_State* L)
  10764. {
  10765. // itemType:isRune()
  10766. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10767. if (itemType) {
  10768. pushBoolean(L, itemType->isRune());
  10769. } else {
  10770. lua_pushnil(L);
  10771. }
  10772. return 1;
  10773. }
  10774.  
  10775. int LuaScriptInterface::luaItemTypeIsStackable(lua_State* L)
  10776. {
  10777. // itemType:isStackable()
  10778. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10779. if (itemType) {
  10780. pushBoolean(L, itemType->stackable);
  10781. } else {
  10782. lua_pushnil(L);
  10783. }
  10784. return 1;
  10785. }
  10786.  
  10787. int LuaScriptInterface::luaItemTypeIsReadable(lua_State* L)
  10788. {
  10789. // itemType:isReadable()
  10790. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10791. if (itemType) {
  10792. pushBoolean(L, itemType->canReadText);
  10793. } else {
  10794. lua_pushnil(L);
  10795. }
  10796. return 1;
  10797. }
  10798.  
  10799. int LuaScriptInterface::luaItemTypeIsWritable(lua_State* L)
  10800. {
  10801. // itemType:isWritable()
  10802. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10803. if (itemType) {
  10804. pushBoolean(L, itemType->canWriteText);
  10805. } else {
  10806. lua_pushnil(L);
  10807. }
  10808. return 1;
  10809. }
  10810.  
  10811. int LuaScriptInterface::luaItemTypeGetType(lua_State* L)
  10812. {
  10813. // itemType:getType()
  10814. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10815. if (itemType) {
  10816. lua_pushnumber(L, itemType->type);
  10817. } else {
  10818. lua_pushnil(L);
  10819. }
  10820. return 1;
  10821. }
  10822.  
  10823. int LuaScriptInterface::luaItemTypeGetId(lua_State* L)
  10824. {
  10825. // itemType:getId()
  10826. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10827. if (itemType) {
  10828. lua_pushnumber(L, itemType->id);
  10829. } else {
  10830. lua_pushnil(L);
  10831. }
  10832. return 1;
  10833. }
  10834.  
  10835. int LuaScriptInterface::luaItemTypeGetClientId(lua_State* L)
  10836. {
  10837. // itemType:getClientId()
  10838. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10839. if (itemType) {
  10840. lua_pushnumber(L, itemType->clientId);
  10841. } else {
  10842. lua_pushnil(L);
  10843. }
  10844. return 1;
  10845. }
  10846.  
  10847. int LuaScriptInterface::luaItemTypeGetName(lua_State* L)
  10848. {
  10849. // itemType:getName()
  10850. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10851. if (itemType) {
  10852. pushString(L, itemType->name);
  10853. } else {
  10854. lua_pushnil(L);
  10855. }
  10856. return 1;
  10857. }
  10858.  
  10859. int LuaScriptInterface::luaItemTypeGetPluralName(lua_State* L)
  10860. {
  10861. // itemType:getPluralName()
  10862. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10863. if (itemType) {
  10864. pushString(L, itemType->getPluralName());
  10865. } else {
  10866. lua_pushnil(L);
  10867. }
  10868. return 1;
  10869. }
  10870.  
  10871. int LuaScriptInterface::luaItemTypeGetArticle(lua_State* L)
  10872. {
  10873. // itemType:getArticle()
  10874. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10875. if (itemType) {
  10876. pushString(L, itemType->article);
  10877. } else {
  10878. lua_pushnil(L);
  10879. }
  10880. return 1;
  10881. }
  10882.  
  10883. int LuaScriptInterface::luaItemTypeGetDescription(lua_State* L)
  10884. {
  10885. // itemType:getDescription()
  10886. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10887. if (itemType) {
  10888. pushString(L, itemType->description);
  10889. } else {
  10890. lua_pushnil(L);
  10891. }
  10892. return 1;
  10893. }
  10894.  
  10895. int LuaScriptInterface::luaItemTypeGetSlotPosition(lua_State *L)
  10896. {
  10897. // itemType:getSlotPosition()
  10898. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10899. if (itemType) {
  10900. lua_pushnumber(L, itemType->slotPosition);
  10901. } else {
  10902. lua_pushnil(L);
  10903. }
  10904. return 1;
  10905. }
  10906.  
  10907. int LuaScriptInterface::luaItemTypeGetCharges(lua_State* L)
  10908. {
  10909. // itemType:getCharges()
  10910. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10911. if (itemType) {
  10912. lua_pushnumber(L, itemType->charges);
  10913. } else {
  10914. lua_pushnil(L);
  10915. }
  10916. return 1;
  10917. }
  10918.  
  10919. int LuaScriptInterface::luaItemTypeGetFluidSource(lua_State* L)
  10920. {
  10921. // itemType:getFluidSource()
  10922. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10923. if (itemType) {
  10924. lua_pushnumber(L, itemType->fluidSource);
  10925. } else {
  10926. lua_pushnil(L);
  10927. }
  10928. return 1;
  10929. }
  10930.  
  10931. int LuaScriptInterface::luaItemTypeGetCapacity(lua_State* L)
  10932. {
  10933. // itemType:getCapacity()
  10934. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10935. if (itemType) {
  10936. lua_pushnumber(L, itemType->maxItems);
  10937. } else {
  10938. lua_pushnil(L);
  10939. }
  10940. return 1;
  10941. }
  10942.  
  10943. int LuaScriptInterface::luaItemTypeGetWeight(lua_State* L)
  10944. {
  10945. // itemType:getWeight([count = 1])
  10946. uint16_t count = getNumber<uint16_t>(L, 2, 1);
  10947.  
  10948. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10949. if (!itemType) {
  10950. lua_pushnil(L);
  10951. return 1;
  10952. }
  10953.  
  10954. uint64_t weight = static_cast<uint64_t>(itemType->weight) * std::max<int32_t>(1, count);
  10955. lua_pushnumber(L, weight);
  10956. return 1;
  10957. }
  10958.  
  10959. int LuaScriptInterface::luaItemTypeGetHitChance(lua_State* L)
  10960. {
  10961. // itemType:getHitChance()
  10962. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10963. if (itemType) {
  10964. lua_pushnumber(L, itemType->hitChance);
  10965. } else {
  10966. lua_pushnil(L);
  10967. }
  10968. return 1;
  10969. }
  10970.  
  10971. int LuaScriptInterface::luaItemTypeGetShootRange(lua_State* L)
  10972. {
  10973. // itemType:getShootRange()
  10974. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10975. if (itemType) {
  10976. lua_pushnumber(L, itemType->shootRange);
  10977. } else {
  10978. lua_pushnil(L);
  10979. }
  10980. return 1;
  10981. }
  10982.  
  10983. int LuaScriptInterface::luaItemTypeGetAttack(lua_State* L)
  10984. {
  10985. // itemType:getAttack()
  10986. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10987. if (itemType) {
  10988. lua_pushnumber(L, itemType->attack);
  10989. } else {
  10990. lua_pushnil(L);
  10991. }
  10992. return 1;
  10993. }
  10994.  
  10995. int LuaScriptInterface::luaItemTypeGetDefense(lua_State* L)
  10996. {
  10997. // itemType:getDefense()
  10998. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10999. if (itemType) {
  11000. lua_pushnumber(L, itemType->defense);
  11001. } else {
  11002. lua_pushnil(L);
  11003. }
  11004. return 1;
  11005. }
  11006.  
  11007. int LuaScriptInterface::luaItemTypeGetExtraDefense(lua_State* L)
  11008. {
  11009. // itemType:getExtraDefense()
  11010. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11011. if (itemType) {
  11012. lua_pushnumber(L, itemType->extraDefense);
  11013. } else {
  11014. lua_pushnil(L);
  11015. }
  11016. return 1;
  11017. }
  11018.  
  11019. int LuaScriptInterface::luaItemTypeGetArmor(lua_State* L)
  11020. {
  11021. // itemType:getArmor()
  11022. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11023. if (itemType) {
  11024. lua_pushnumber(L, itemType->armor);
  11025. } else {
  11026. lua_pushnil(L);
  11027. }
  11028. return 1;
  11029. }
  11030.  
  11031. int LuaScriptInterface::luaItemTypeGetWeaponType(lua_State* L)
  11032. {
  11033. // itemType:getWeaponType()
  11034. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11035. if (itemType) {
  11036. lua_pushnumber(L, itemType->weaponType);
  11037. } else {
  11038. lua_pushnil(L);
  11039. }
  11040. return 1;
  11041. }
  11042.  
  11043. int LuaScriptInterface::luaItemTypeGetElementType(lua_State* L)
  11044. {
  11045. // itemType:getElementType()
  11046. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11047. if (!itemType) {
  11048. lua_pushnil(L);
  11049. return 1;
  11050. }
  11051.  
  11052. auto& abilities = itemType->abilities;
  11053. if (abilities) {
  11054. lua_pushnumber(L, abilities->elementType);
  11055. } else {
  11056. lua_pushnil(L);
  11057. }
  11058. return 1;
  11059. }
  11060.  
  11061. int LuaScriptInterface::luaItemTypeGetElementDamage(lua_State* L)
  11062. {
  11063. // itemType:getElementDamage()
  11064. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11065. if (!itemType) {
  11066. lua_pushnil(L);
  11067. return 1;
  11068. }
  11069.  
  11070. auto& abilities = itemType->abilities;
  11071. if (abilities) {
  11072. lua_pushnumber(L, abilities->elementDamage);
  11073. } else {
  11074. lua_pushnil(L);
  11075. }
  11076. return 1;
  11077. }
  11078.  
  11079. int LuaScriptInterface::luaItemTypeGetTransformEquipId(lua_State* L)
  11080. {
  11081. // itemType:getTransformEquipId()
  11082. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11083. if (itemType) {
  11084. lua_pushnumber(L, itemType->transformEquipTo);
  11085. } else {
  11086. lua_pushnil(L);
  11087. }
  11088. return 1;
  11089. }
  11090.  
  11091. int LuaScriptInterface::luaItemTypeGetTransformDeEquipId(lua_State* L)
  11092. {
  11093. // itemType:getTransformDeEquipId()
  11094. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11095. if (itemType) {
  11096. lua_pushnumber(L, itemType->transformDeEquipTo);
  11097. } else {
  11098. lua_pushnil(L);
  11099. }
  11100. return 1;
  11101. }
  11102.  
  11103. int LuaScriptInterface::luaItemTypeGetDestroyId(lua_State* L)
  11104. {
  11105. // itemType:getDestroyId()
  11106. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11107. if (itemType) {
  11108. lua_pushnumber(L, itemType->destroyTo);
  11109. } else {
  11110. lua_pushnil(L);
  11111. }
  11112. return 1;
  11113. }
  11114.  
  11115. int LuaScriptInterface::luaItemTypeGetDecayId(lua_State* L)
  11116. {
  11117. // itemType:getDecayId()
  11118. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11119. if (itemType) {
  11120. lua_pushnumber(L, itemType->decayTo);
  11121. } else {
  11122. lua_pushnil(L);
  11123. }
  11124. return 1;
  11125. }
  11126.  
  11127. int LuaScriptInterface::luaItemTypeGetRequiredLevel(lua_State* L)
  11128. {
  11129. // itemType:getRequiredLevel()
  11130. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11131. if (itemType) {
  11132. lua_pushnumber(L, itemType->minReqLevel);
  11133. } else {
  11134. lua_pushnil(L);
  11135. }
  11136. return 1;
  11137. }
  11138.  
  11139. int LuaScriptInterface::luaItemTypeHasSubType(lua_State* L)
  11140. {
  11141. // itemType:hasSubType()
  11142. const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  11143. if (itemType) {
  11144. pushBoolean(L, itemType->hasSubType());
  11145. } else {
  11146. lua_pushnil(L);
  11147. }
  11148. return 1;
  11149. }
  11150.  
  11151. // Combat
  11152. int LuaScriptInterface::luaCombatCreate(lua_State* L)
  11153. {
  11154. // Combat()
  11155. pushUserdata<Combat>(L, g_luaEnvironment.createCombatObject(getScriptEnv()->getScriptInterface()));
  11156. setMetatable(L, -1, "Combat");
  11157. return 1;
  11158. }
  11159.  
  11160. int LuaScriptInterface::luaCombatSetParameter(lua_State* L)
  11161. {
  11162. // combat:setParameter(key, value)
  11163. Combat* combat = getUserdata<Combat>(L, 1);
  11164. if (!combat) {
  11165. lua_pushnil(L);
  11166. return 1;
  11167. }
  11168.  
  11169. CombatParam_t key = getNumber<CombatParam_t>(L, 2);
  11170. uint32_t value;
  11171. if (isBoolean(L, 3)) {
  11172. value = getBoolean(L, 3) ? 1 : 0;
  11173. } else {
  11174. value = getNumber<uint32_t>(L, 3);
  11175. }
  11176. combat->setParam(key, value);
  11177. pushBoolean(L, true);
  11178. return 1;
  11179. }
  11180.  
  11181. int LuaScriptInterface::luaCombatSetFormula(lua_State* L)
  11182. {
  11183. // combat:setFormula(type, mina, minb, maxa, maxb)
  11184. Combat* combat = getUserdata<Combat>(L, 1);
  11185. if (!combat) {
  11186. lua_pushnil(L);
  11187. return 1;
  11188. }
  11189.  
  11190. formulaType_t type = getNumber<formulaType_t>(L, 2);
  11191. double mina = getNumber<double>(L, 3);
  11192. double minb = getNumber<double>(L, 4);
  11193. double maxa = getNumber<double>(L, 5);
  11194. double maxb = getNumber<double>(L, 6);
  11195. combat->setPlayerCombatValues(type, mina, minb, maxa, maxb);
  11196. pushBoolean(L, true);
  11197. return 1;
  11198. }
  11199.  
  11200. int LuaScriptInterface::luaCombatSetArea(lua_State* L)
  11201. {
  11202. // combat:setArea(area)
  11203. if (getScriptEnv()->getScriptId() != EVENT_ID_LOADING) {
  11204. reportErrorFunc("This function can only be used while loading the script.");
  11205. lua_pushnil(L);
  11206. return 1;
  11207. }
  11208.  
  11209. const AreaCombat* area = g_luaEnvironment.getAreaObject(getNumber<uint32_t>(L, 2));
  11210. if (!area) {
  11211. reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  11212. lua_pushnil(L);
  11213. return 1;
  11214. }
  11215.  
  11216. Combat* combat = getUserdata<Combat>(L, 1);
  11217. if (combat) {
  11218. combat->setArea(new AreaCombat(*area));
  11219. pushBoolean(L, true);
  11220. } else {
  11221. lua_pushnil(L);
  11222. }
  11223. return 1;
  11224. }
  11225.  
  11226. int LuaScriptInterface::luaCombatSetCondition(lua_State* L)
  11227. {
  11228. // combat:setCondition(condition)
  11229. Condition* condition = getUserdata<Condition>(L, 2);
  11230. Combat* combat = getUserdata<Combat>(L, 1);
  11231. if (combat && condition) {
  11232. combat->setCondition(condition->clone());
  11233. pushBoolean(L, true);
  11234. } else {
  11235. lua_pushnil(L);
  11236. }
  11237. return 1;
  11238. }
  11239.  
  11240. int LuaScriptInterface::luaCombatSetCallback(lua_State* L)
  11241. {
  11242. // combat:setCallback(key, function)
  11243. Combat* combat = getUserdata<Combat>(L, 1);
  11244. if (!combat) {
  11245. lua_pushnil(L);
  11246. return 1;
  11247. }
  11248.  
  11249. CallBackParam_t key = getNumber<CallBackParam_t>(L, 2);
  11250. if (!combat->setCallback(key)) {
  11251. lua_pushnil(L);
  11252. return 1;
  11253. }
  11254.  
  11255. CallBack* callback = combat->getCallback(key);
  11256. if (!callback) {
  11257. lua_pushnil(L);
  11258. return 1;
  11259. }
  11260.  
  11261. const std::string& function = getString(L, 3);
  11262. pushBoolean(L, callback->loadCallBack(getScriptEnv()->getScriptInterface(), function));
  11263. return 1;
  11264. }
  11265.  
  11266. int LuaScriptInterface::luaCombatSetOrigin(lua_State* L)
  11267. {
  11268. // combat:setOrigin(origin)
  11269. Combat* combat = getUserdata<Combat>(L, 1);
  11270. if (combat) {
  11271. combat->setOrigin(getNumber<CombatOrigin>(L, 2));
  11272. pushBoolean(L, true);
  11273. } else {
  11274. lua_pushnil(L);
  11275. }
  11276. return 1;
  11277. }
  11278.  
  11279. int LuaScriptInterface::luaCombatExecute(lua_State* L)
  11280. {
  11281. // combat:execute(creature, variant)
  11282. Combat* combat = getUserdata<Combat>(L, 1);
  11283. if (!combat) {
  11284. pushBoolean(L, false);
  11285. return 1;
  11286. }
  11287.  
  11288. Creature* creature = getCreature(L, 2);
  11289.  
  11290. const LuaVariant& variant = getVariant(L, 3);
  11291. switch (variant.type) {
  11292. case VARIANT_NUMBER: {
  11293. Creature* target = g_game.getCreatureByID(variant.number);
  11294. if (!target) {
  11295. pushBoolean(L, false);
  11296. return 1;
  11297. }
  11298.  
  11299. if (combat->hasArea()) {
  11300. combat->doCombat(creature, target->getPosition());
  11301. } else {
  11302. combat->doCombat(creature, target);
  11303. }
  11304. break;
  11305. }
  11306.  
  11307. case VARIANT_POSITION: {
  11308. combat->doCombat(creature, variant.pos);
  11309. break;
  11310. }
  11311.  
  11312. case VARIANT_TARGETPOSITION: {
  11313. if (combat->hasArea()) {
  11314. combat->doCombat(creature, variant.pos);
  11315. } else {
  11316. combat->postCombatEffects(creature, variant.pos);
  11317. g_game.addMagicEffect(variant.pos, CONST_ME_POFF);
  11318. }
  11319. break;
  11320. }
  11321.  
  11322. case VARIANT_STRING: {
  11323. Player* target = g_game.getPlayerByName(variant.text);
  11324. if (!target) {
  11325. pushBoolean(L, false);
  11326. return 1;
  11327. }
  11328.  
  11329. combat->doCombat(creature, target);
  11330. break;
  11331. }
  11332.  
  11333. case VARIANT_NONE: {
  11334. reportErrorFunc(getErrorDesc(LUA_ERROR_VARIANT_NOT_FOUND));
  11335. pushBoolean(L, false);
  11336. return 1;
  11337. }
  11338.  
  11339. default: {
  11340. break;
  11341. }
  11342. }
  11343.  
  11344. pushBoolean(L, true);
  11345. return 1;
  11346. }
  11347.  
  11348. // Condition
  11349. int LuaScriptInterface::luaConditionCreate(lua_State* L)
  11350. {
  11351. // Condition(conditionType[, conditionId = CONDITIONID_COMBAT])
  11352. ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
  11353. ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
  11354.  
  11355. Condition* condition = Condition::createCondition(conditionId, conditionType, 0, 0);
  11356. if (condition) {
  11357. pushUserdata<Condition>(L, condition);
  11358. setMetatable(L, -1, "Condition");
  11359. } else {
  11360. lua_pushnil(L);
  11361. }
  11362. return 1;
  11363. }
  11364.  
  11365. int LuaScriptInterface::luaConditionDelete(lua_State* L)
  11366. {
  11367. // condition:delete()
  11368. Condition** conditionPtr = getRawUserdata<Condition>(L, 1);
  11369. if (conditionPtr && *conditionPtr) {
  11370. delete *conditionPtr;
  11371. *conditionPtr = nullptr;
  11372. }
  11373. return 0;
  11374. }
  11375.  
  11376. int LuaScriptInterface::luaConditionGetId(lua_State* L)
  11377. {
  11378. // condition:getId()
  11379. Condition* condition = getUserdata<Condition>(L, 1);
  11380. if (condition) {
  11381. lua_pushnumber(L, condition->getId());
  11382. } else {
  11383. lua_pushnil(L);
  11384. }
  11385. return 1;
  11386. }
  11387.  
  11388. int LuaScriptInterface::luaConditionGetSubId(lua_State* L)
  11389. {
  11390. // condition:getSubId()
  11391. Condition* condition = getUserdata<Condition>(L, 1);
  11392. if (condition) {
  11393. lua_pushnumber(L, condition->getSubId());
  11394. } else {
  11395. lua_pushnil(L);
  11396. }
  11397. return 1;
  11398. }
  11399.  
  11400. int LuaScriptInterface::luaConditionGetType(lua_State* L)
  11401. {
  11402. // condition:getType()
  11403. Condition* condition = getUserdata<Condition>(L, 1);
  11404. if (condition) {
  11405. lua_pushnumber(L, condition->getType());
  11406. } else {
  11407. lua_pushnil(L);
  11408. }
  11409. return 1;
  11410. }
  11411.  
  11412. int LuaScriptInterface::luaConditionGetIcons(lua_State* L)
  11413. {
  11414. // condition:getIcons()
  11415. Condition* condition = getUserdata<Condition>(L, 1);
  11416. if (condition) {
  11417. lua_pushnumber(L, condition->getIcons());
  11418. } else {
  11419. lua_pushnil(L);
  11420. }
  11421. return 1;
  11422. }
  11423.  
  11424. int LuaScriptInterface::luaConditionGetEndTime(lua_State* L)
  11425. {
  11426. // condition:getEndTime()
  11427. Condition* condition = getUserdata<Condition>(L, 1);
  11428. if (condition) {
  11429. lua_pushnumber(L, condition->getEndTime());
  11430. } else {
  11431. lua_pushnil(L);
  11432. }
  11433. return 1;
  11434. }
  11435.  
  11436. int LuaScriptInterface::luaConditionClone(lua_State* L)
  11437. {
  11438. // condition:clone()
  11439. Condition* condition = getUserdata<Condition>(L, 1);
  11440. if (condition) {
  11441. pushUserdata<Condition>(L, condition->clone());
  11442. setMetatable(L, -1, "Condition");
  11443. } else {
  11444. lua_pushnil(L);
  11445. }
  11446. return 1;
  11447. }
  11448.  
  11449. int LuaScriptInterface::luaConditionGetTicks(lua_State* L)
  11450. {
  11451. // condition:getTicks()
  11452. Condition* condition = getUserdata<Condition>(L, 1);
  11453. if (condition) {
  11454. lua_pushnumber(L, condition->getTicks());
  11455. } else {
  11456. lua_pushnil(L);
  11457. }
  11458. return 1;
  11459. }
  11460.  
  11461. int LuaScriptInterface::luaConditionSetTicks(lua_State* L)
  11462. {
  11463. // condition:setTicks(ticks)
  11464. int32_t ticks = getNumber<int32_t>(L, 2);
  11465. Condition* condition = getUserdata<Condition>(L, 1);
  11466. if (condition) {
  11467. condition->setTicks(ticks);
  11468. pushBoolean(L, true);
  11469. } else {
  11470. lua_pushnil(L);
  11471. }
  11472. return 1;
  11473. }
  11474.  
  11475. int LuaScriptInterface::luaConditionSetParameter(lua_State* L)
  11476. {
  11477. // condition:setParameter(key, value)
  11478. Condition* condition = getUserdata<Condition>(L, 1);
  11479. if (!condition) {
  11480. lua_pushnil(L);
  11481. return 1;
  11482. }
  11483.  
  11484. ConditionParam_t key = getNumber<ConditionParam_t>(L, 2);
  11485. int32_t value;
  11486. if (isBoolean(L, 3)) {
  11487. value = getBoolean(L, 3) ? 1 : 0;
  11488. } else {
  11489. value = getNumber<int32_t>(L, 3);
  11490. }
  11491. condition->setParam(key, value);
  11492. pushBoolean(L, true);
  11493. return 1;
  11494. }
  11495.  
  11496. int LuaScriptInterface::luaConditionSetFormula(lua_State* L)
  11497. {
  11498. // condition:setFormula(mina, minb, maxa, maxb)
  11499. double maxb = getNumber<double>(L, 5);
  11500. double maxa = getNumber<double>(L, 4);
  11501. double minb = getNumber<double>(L, 3);
  11502. double mina = getNumber<double>(L, 2);
  11503. ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(getUserdata<Condition>(L, 1));
  11504. if (condition) {
  11505. condition->setFormulaVars(mina, minb, maxa, maxb);
  11506. pushBoolean(L, true);
  11507. } else {
  11508. lua_pushnil(L);
  11509. }
  11510. return 1;
  11511. }
  11512.  
  11513. int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)
  11514. {
  11515. // condition:setOutfit(outfit)
  11516. // condition:setOutfit(lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet[, lookAddons[, lookMount]])
  11517. Outfit_t outfit;
  11518. if (isTable(L, 2)) {
  11519. outfit = getOutfit(L, 2);
  11520. } else {
  11521. outfit.lookMount = getNumber<uint16_t>(L, 9, outfit.lookMount);
  11522. outfit.lookAddons = getNumber<uint8_t>(L, 8, outfit.lookAddons);
  11523. outfit.lookFeet = getNumber<uint8_t>(L, 7);
  11524. outfit.lookLegs = getNumber<uint8_t>(L, 6);
  11525. outfit.lookBody = getNumber<uint8_t>(L, 5);
  11526. outfit.lookHead = getNumber<uint8_t>(L, 4);
  11527. outfit.lookType = getNumber<uint16_t>(L, 3);
  11528. outfit.lookTypeEx = getNumber<uint16_t>(L, 2);
  11529. }
  11530.  
  11531. ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(getUserdata<Condition>(L, 1));
  11532. if (condition) {
  11533. condition->setOutfit(outfit);
  11534. pushBoolean(L, true);
  11535. } else {
  11536. lua_pushnil(L);
  11537. }
  11538. return 1;
  11539. }
  11540.  
  11541. int LuaScriptInterface::luaConditionAddDamage(lua_State* L)
  11542. {
  11543. // condition:addDamage(rounds, time, value)
  11544. int32_t value = getNumber<int32_t>(L, 4);
  11545. int32_t time = getNumber<int32_t>(L, 3);
  11546. int32_t rounds = getNumber<int32_t>(L, 2);
  11547. ConditionDamage* condition = dynamic_cast<ConditionDamage*>(getUserdata<Condition>(L, 1));
  11548. if (condition) {
  11549. pushBoolean(L, condition->addDamage(rounds, time, value));
  11550. } else {
  11551. lua_pushnil(L);
  11552. }
  11553. return 1;
  11554. }
  11555.  
  11556. // MonsterType
  11557. int LuaScriptInterface::luaMonsterTypeCreate(lua_State* L)
  11558. {
  11559. // MonsterType(name)
  11560. MonsterType* monsterType = g_monsters.getMonsterType(getString(L, 2));
  11561. if (monsterType) {
  11562. pushUserdata<MonsterType>(L, monsterType);
  11563. setMetatable(L, -1, "MonsterType");
  11564. } else {
  11565. lua_pushnil(L);
  11566. }
  11567. return 1;
  11568. }
  11569.  
  11570. int LuaScriptInterface::luaMonsterTypeIsAttackable(lua_State* L)
  11571. {
  11572. // monsterType:isAttackable()
  11573. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11574. if (monsterType) {
  11575. pushBoolean(L, monsterType->isAttackable);
  11576. } else {
  11577. lua_pushnil(L);
  11578. }
  11579. return 1;
  11580. }
  11581.  
  11582. int LuaScriptInterface::luaMonsterTypeIsConvinceable(lua_State* L)
  11583. {
  11584. // monsterType:isConvinceable()
  11585. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11586. if (monsterType) {
  11587. pushBoolean(L, monsterType->isConvinceable);
  11588. } else {
  11589. lua_pushnil(L);
  11590. }
  11591. return 1;
  11592. }
  11593.  
  11594. int LuaScriptInterface::luaMonsterTypeIsSummonable(lua_State* L)
  11595. {
  11596. // monsterType:isSummonable()
  11597. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11598. if (monsterType) {
  11599. pushBoolean(L, monsterType->isSummonable);
  11600. } else {
  11601. lua_pushnil(L);
  11602. }
  11603. return 1;
  11604. }
  11605.  
  11606. int LuaScriptInterface::luaMonsterTypeIsIllusionable(lua_State* L)
  11607. {
  11608. // monsterType:isIllusionable()
  11609. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11610. if (monsterType) {
  11611. pushBoolean(L, monsterType->isIllusionable);
  11612. } else {
  11613. lua_pushnil(L);
  11614. }
  11615. return 1;
  11616. }
  11617.  
  11618. int LuaScriptInterface::luaMonsterTypeIsHostile(lua_State* L)
  11619. {
  11620. // monsterType:isHostile()
  11621. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11622. if (monsterType) {
  11623. pushBoolean(L, monsterType->isHostile);
  11624. } else {
  11625. lua_pushnil(L);
  11626. }
  11627. return 1;
  11628. }
  11629.  
  11630. int LuaScriptInterface::luaMonsterTypeIsPushable(lua_State* L)
  11631. {
  11632. // monsterType:isPushable()
  11633. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11634. if (monsterType) {
  11635. pushBoolean(L, monsterType->pushable);
  11636. } else {
  11637. lua_pushnil(L);
  11638. }
  11639. return 1;
  11640. }
  11641.  
  11642. int LuaScriptInterface::luaMonsterTypeIsHealthShown(lua_State* L)
  11643. {
  11644. // monsterType:isHealthShown()
  11645. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11646. if (monsterType) {
  11647. pushBoolean(L, !monsterType->hiddenHealth);
  11648. } else {
  11649. lua_pushnil(L);
  11650. }
  11651. return 1;
  11652. }
  11653.  
  11654. int LuaScriptInterface::luaMonsterTypeIsRewardBoss(lua_State* L)
  11655. {
  11656. // monsterType:isRewardBoss()
  11657. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11658. if (monsterType) {
  11659. pushBoolean(L, monsterType->isRewardBoss);
  11660. } else {
  11661. lua_pushnil(L);
  11662. }
  11663. return 1;
  11664. }
  11665.  
  11666. int LuaScriptInterface::luaMonsterTypeCanPushItems(lua_State* L)
  11667. {
  11668. // monsterType:canPushItems()
  11669. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11670. if (monsterType) {
  11671. pushBoolean(L, monsterType->canPushItems);
  11672. } else {
  11673. lua_pushnil(L);
  11674. }
  11675. return 1;
  11676. }
  11677.  
  11678. int LuaScriptInterface::luaMonsterTypeCanPushCreatures(lua_State* L)
  11679. {
  11680. // monsterType:canPushCreatures()
  11681. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11682. if (monsterType) {
  11683. pushBoolean(L, monsterType->canPushCreatures);
  11684. } else {
  11685. lua_pushnil(L);
  11686. }
  11687. return 1;
  11688. }
  11689.  
  11690. int LuaScriptInterface::luaMonsterTypeGetName(lua_State* L)
  11691. {
  11692. // monsterType:getName()
  11693. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11694. if (monsterType) {
  11695. pushString(L, monsterType->name);
  11696. } else {
  11697. lua_pushnil(L);
  11698. }
  11699. return 1;
  11700. }
  11701.  
  11702. int LuaScriptInterface::luaMonsterTypeGetNameDescription(lua_State* L)
  11703. {
  11704. // monsterType:getNameDescription()
  11705. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11706. if (monsterType) {
  11707. pushString(L, monsterType->nameDescription);
  11708. } else {
  11709. lua_pushnil(L);
  11710. }
  11711. return 1;
  11712. }
  11713.  
  11714. int LuaScriptInterface::luaMonsterTypeGetHealth(lua_State* L)
  11715. {
  11716. // monsterType:getHealth()
  11717. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11718. if (monsterType) {
  11719. lua_pushnumber(L, monsterType->health);
  11720. } else {
  11721. lua_pushnil(L);
  11722. }
  11723. return 1;
  11724. }
  11725.  
  11726. int LuaScriptInterface::luaMonsterTypeGetMaxHealth(lua_State* L)
  11727. {
  11728. // monsterType:getMaxHealth()
  11729. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11730. if (monsterType) {
  11731. lua_pushnumber(L, monsterType->healthMax);
  11732. } else {
  11733. lua_pushnil(L);
  11734. }
  11735. return 1;
  11736. }
  11737.  
  11738. int LuaScriptInterface::luaMonsterTypeGetRunHealth(lua_State* L)
  11739. {
  11740. // monsterType:getRunHealth()
  11741. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11742. if (monsterType) {
  11743. lua_pushnumber(L, monsterType->runAwayHealth);
  11744. } else {
  11745. lua_pushnil(L);
  11746. }
  11747. return 1;
  11748. }
  11749.  
  11750. int LuaScriptInterface::luaMonsterTypeGetExperience(lua_State* L)
  11751. {
  11752. // monsterType:getExperience()
  11753. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11754. if (monsterType) {
  11755. lua_pushnumber(L, monsterType->experience);
  11756. } else {
  11757. lua_pushnil(L);
  11758. }
  11759. return 1;
  11760. }
  11761.  
  11762. int LuaScriptInterface::luaMonsterTypeGetCombatImmunities(lua_State* L)
  11763. {
  11764. // monsterType:getCombatImmunities()
  11765. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11766. if (monsterType) {
  11767. lua_pushnumber(L, monsterType->damageImmunities);
  11768. } else {
  11769. lua_pushnil(L);
  11770. }
  11771. return 1;
  11772. }
  11773.  
  11774. int LuaScriptInterface::luaMonsterTypeGetConditionImmunities(lua_State* L)
  11775. {
  11776. // monsterType:getConditionImmunities()
  11777. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11778. if (monsterType) {
  11779. lua_pushnumber(L, monsterType->conditionImmunities);
  11780. } else {
  11781. lua_pushnil(L);
  11782. }
  11783. return 1;
  11784. }
  11785.  
  11786. int LuaScriptInterface::luaMonsterTypeGetAttackList(lua_State* L)
  11787. {
  11788. // monsterType:getAttackList()
  11789. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11790. if (!monsterType) {
  11791. lua_pushnil(L);
  11792. return 1;
  11793. }
  11794.  
  11795. lua_createtable(L, monsterType->attackSpells.size(), 0);
  11796.  
  11797. int index = 0;
  11798. for (const auto& spellBlock : monsterType->attackSpells) {
  11799. lua_createtable(L, 0, 8);
  11800.  
  11801. setField(L, "chance", spellBlock.chance);
  11802. setField(L, "isCombatSpell", spellBlock.combatSpell ? 1 : 0);
  11803. setField(L, "isMelee", spellBlock.isMelee ? 1 : 0);
  11804. setField(L, "minCombatValue", spellBlock.minCombatValue);
  11805. setField(L, "maxCombatValue", spellBlock.maxCombatValue);
  11806. setField(L, "range", spellBlock.range);
  11807. setField(L, "speed", spellBlock.speed);
  11808. pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
  11809. lua_setfield(L, -2, "spell");
  11810.  
  11811. lua_rawseti(L, -2, ++index);
  11812. }
  11813. return 1;
  11814. }
  11815.  
  11816. int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
  11817. {
  11818. // monsterType:getDefenseList()
  11819. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11820. if (!monsterType) {
  11821. lua_pushnil(L);
  11822. return 1;
  11823. }
  11824.  
  11825. lua_createtable(L, monsterType->defenseSpells.size(), 0);
  11826.  
  11827.  
  11828. int index = 0;
  11829. for (const auto& spellBlock : monsterType->defenseSpells) {
  11830. lua_createtable(L, 0, 8);
  11831.  
  11832. setField(L, "chance", spellBlock.chance);
  11833. setField(L, "isCombatSpell", spellBlock.combatSpell ? 1 : 0);
  11834. setField(L, "isMelee", spellBlock.isMelee ? 1 : 0);
  11835. setField(L, "minCombatValue", spellBlock.minCombatValue);
  11836. setField(L, "maxCombatValue", spellBlock.maxCombatValue);
  11837. setField(L, "range", spellBlock.range);
  11838. setField(L, "speed", spellBlock.speed);
  11839. pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
  11840. lua_setfield(L, -2, "spell");
  11841.  
  11842. lua_rawseti(L, -2, ++index);
  11843. }
  11844. return 1;
  11845. }
  11846.  
  11847. int LuaScriptInterface::luaMonsterTypeGetElementList(lua_State* L)
  11848. {
  11849. // monsterType:getElementList()
  11850. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11851. if (!monsterType) {
  11852. lua_pushnil(L);
  11853. return 1;
  11854. }
  11855.  
  11856. lua_createtable(L, monsterType->elementMap.size(), 0);
  11857. for (const auto& elementEntry : monsterType->elementMap) {
  11858. lua_pushnumber(L, elementEntry.second);
  11859. lua_rawseti(L, -2, elementEntry.first);
  11860. }
  11861. return 1;
  11862. }
  11863.  
  11864. int LuaScriptInterface::luaMonsterTypeGetVoices(lua_State* L)
  11865. {
  11866. // monsterType:getVoices()
  11867. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11868. if (!monsterType) {
  11869. lua_pushnil(L);
  11870. return 1;
  11871. }
  11872.  
  11873. int index = 0;
  11874. lua_createtable(L, monsterType->voiceVector.size(), 0);
  11875. for (const auto& voiceBlock : monsterType->voiceVector) {
  11876. lua_createtable(L, 0, 2);
  11877. setField(L, "text", voiceBlock.text);
  11878. setField(L, "yellText", voiceBlock.yellText);
  11879. lua_rawseti(L, -2, ++index);
  11880. }
  11881. return 1;
  11882. }
  11883.  
  11884. int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L)
  11885. {
  11886. // monsterType:getLoot()
  11887. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11888. if (!monsterType) {
  11889. lua_pushnil(L);
  11890. return 1;
  11891. }
  11892.  
  11893. static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) {
  11894. lua_createtable(L, lootList.size(), 0);
  11895.  
  11896. int index = 0;
  11897. for (const auto& lootBlock : lootList) {
  11898. lua_createtable(L, 0, 8);
  11899.  
  11900. setField(L, "itemId", lootBlock.id);
  11901. setField(L, "chance", lootBlock.chance);
  11902. setField(L, "subType", lootBlock.subType);
  11903. setField(L, "maxCount", lootBlock.countmax);
  11904. setField(L, "actionId", lootBlock.actionId);
  11905. setField(L, "text", lootBlock.text);
  11906. pushBoolean(L, lootBlock.unique);
  11907. lua_setfield(L, -2, "unique");
  11908.  
  11909. parseLoot(lootBlock.childLoot);
  11910. lua_setfield(L, -2, "childLoot");
  11911.  
  11912. lua_rawseti(L, -2, ++index);
  11913. }
  11914. };
  11915. parseLoot(monsterType->lootItems);
  11916. return 1;
  11917. }
  11918.  
  11919. int LuaScriptInterface::luaMonsterTypeGetCreatureEvents(lua_State* L)
  11920. {
  11921. // monsterType:getCreatureEvents()
  11922. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11923. if (!monsterType) {
  11924. lua_pushnil(L);
  11925. return 1;
  11926. }
  11927.  
  11928. int index = 0;
  11929. lua_createtable(L, monsterType->scripts.size(), 0);
  11930. for (const std::string& creatureEvent : monsterType->scripts) {
  11931. pushString(L, creatureEvent);
  11932. lua_rawseti(L, -2, ++index);
  11933. }
  11934. return 1;
  11935. }
  11936.  
  11937. int LuaScriptInterface::luaMonsterTypeGetSummonList(lua_State* L)
  11938. {
  11939. // monsterType:getSummonList()
  11940. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11941. if (!monsterType) {
  11942. lua_pushnil(L);
  11943. return 1;
  11944. }
  11945.  
  11946. int index = 0;
  11947. lua_createtable(L, monsterType->summons.size(), 0);
  11948. for (const auto& summonBlock : monsterType->summons) {
  11949. lua_createtable(L, 0, 3);
  11950. setField(L, "name", summonBlock.name);
  11951. setField(L, "speed", summonBlock.speed);
  11952. setField(L, "chance", summonBlock.chance);
  11953. lua_rawseti(L, -2, ++index);
  11954. }
  11955. return 1;
  11956. }
  11957.  
  11958. int LuaScriptInterface::luaMonsterTypeGetMaxSummons(lua_State* L)
  11959. {
  11960. // monsterType:getMaxSummons()
  11961. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11962. if (monsterType) {
  11963. lua_pushnumber(L, monsterType->maxSummons);
  11964. } else {
  11965. lua_pushnil(L);
  11966. }
  11967. return 1;
  11968. }
  11969.  
  11970. int LuaScriptInterface::luaMonsterTypeGetArmor(lua_State* L)
  11971. {
  11972. // monsterType:getArmor()
  11973. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11974. if (monsterType) {
  11975. lua_pushnumber(L, monsterType->armor);
  11976. } else {
  11977. lua_pushnil(L);
  11978. }
  11979. return 1;
  11980. }
  11981.  
  11982. int LuaScriptInterface::luaMonsterTypeGetDefense(lua_State* L)
  11983. {
  11984. // monsterType:getDefense()
  11985. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11986. if (monsterType) {
  11987. lua_pushnumber(L, monsterType->defense);
  11988. } else {
  11989. lua_pushnil(L);
  11990. }
  11991. return 1;
  11992. }
  11993.  
  11994. int LuaScriptInterface::luaMonsterTypeGetOutfit(lua_State* L)
  11995. {
  11996. // monsterType:getOutfit()
  11997. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11998. if (monsterType) {
  11999. pushOutfit(L, monsterType->outfit);
  12000. } else {
  12001. lua_pushnil(L);
  12002. }
  12003. return 1;
  12004. }
  12005.  
  12006. int LuaScriptInterface::luaMonsterTypeGetRace(lua_State* L)
  12007. {
  12008. // monsterType:getRace()
  12009. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12010. if (monsterType) {
  12011. lua_pushnumber(L, monsterType->race);
  12012. } else {
  12013. lua_pushnil(L);
  12014. }
  12015. return 1;
  12016. }
  12017.  
  12018. int LuaScriptInterface::luaMonsterTypeGetCorpseId(lua_State* L)
  12019. {
  12020. // monsterType:getCorpseId()
  12021. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12022. if (monsterType) {
  12023. lua_pushnumber(L, monsterType->lookcorpse);
  12024. } else {
  12025. lua_pushnil(L);
  12026. }
  12027. return 1;
  12028. }
  12029.  
  12030. int LuaScriptInterface::luaMonsterTypeGetManaCost(lua_State* L)
  12031. {
  12032. // monsterType:getManaCost()
  12033. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12034. if (monsterType) {
  12035. lua_pushnumber(L, monsterType->manaCost);
  12036. } else {
  12037. lua_pushnil(L);
  12038. }
  12039. return 1;
  12040. }
  12041.  
  12042. int LuaScriptInterface::luaMonsterTypeGetBaseSpeed(lua_State* L)
  12043. {
  12044. // monsterType:getBaseSpeed()
  12045. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12046. if (monsterType) {
  12047. lua_pushnumber(L, monsterType->baseSpeed);
  12048. } else {
  12049. lua_pushnil(L);
  12050. }
  12051. return 1;
  12052. }
  12053.  
  12054. int LuaScriptInterface::luaMonsterTypeGetLight(lua_State* L)
  12055. {
  12056. // monsterType:getLight()
  12057. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12058. if (!monsterType) {
  12059. lua_pushnil(L);
  12060. return 1;
  12061. }
  12062.  
  12063. lua_pushnumber(L, monsterType->lightLevel);
  12064. lua_pushnumber(L, monsterType->lightColor);
  12065. return 2;
  12066. }
  12067.  
  12068. int LuaScriptInterface::luaMonsterTypeGetStaticAttackChance(lua_State* L)
  12069. {
  12070. // monsterType:getStaticAttackChance()
  12071. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12072. if (monsterType) {
  12073. lua_pushnumber(L, monsterType->staticAttackChance);
  12074. } else {
  12075. lua_pushnil(L);
  12076. }
  12077. return 1;
  12078. }
  12079.  
  12080. int LuaScriptInterface::luaMonsterTypeGetTargetDistance(lua_State* L)
  12081. {
  12082. // monsterType:getTargetDistance()
  12083. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12084. if (monsterType) {
  12085. lua_pushnumber(L, monsterType->targetDistance);
  12086. } else {
  12087. lua_pushnil(L);
  12088. }
  12089. return 1;
  12090. }
  12091.  
  12092. int LuaScriptInterface::luaMonsterTypeGetYellChance(lua_State* L)
  12093. {
  12094. // monsterType:getYellChance()
  12095. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12096. if (monsterType) {
  12097. lua_pushnumber(L, monsterType->yellChance);
  12098. } else {
  12099. lua_pushnil(L);
  12100. }
  12101. return 1;
  12102. }
  12103.  
  12104. int LuaScriptInterface::luaMonsterTypeGetYellSpeedTicks(lua_State* L)
  12105. {
  12106. // monsterType:getYellSpeedTicks()
  12107. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12108. if (monsterType) {
  12109. lua_pushnumber(L, monsterType->yellSpeedTicks);
  12110. } else {
  12111. lua_pushnil(L);
  12112. }
  12113. return 1;
  12114. }
  12115.  
  12116. int LuaScriptInterface::luaMonsterTypeGetChangeTargetChance(lua_State* L)
  12117. {
  12118. // monsterType:getChangeTargetChance()
  12119. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12120. if (monsterType) {
  12121. lua_pushnumber(L, monsterType->changeTargetChance);
  12122. } else {
  12123. lua_pushnil(L);
  12124. }
  12125. return 1;
  12126. }
  12127.  
  12128. int LuaScriptInterface::luaMonsterTypeGetChangeTargetSpeed(lua_State* L)
  12129. {
  12130. // monsterType:getChangeTargetSpeed()
  12131. MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  12132. if (monsterType) {
  12133. lua_pushnumber(L, monsterType->changeTargetSpeed);
  12134. } else {
  12135. lua_pushnil(L);
  12136. }
  12137. return 1;
  12138. }
  12139.  
  12140. // Party
  12141. int LuaScriptInterface::luaPartyDisband(lua_State* L)
  12142. {
  12143. // party:disband()
  12144. Party** partyPtr = getRawUserdata<Party>(L, 1);
  12145. if (partyPtr && *partyPtr) {
  12146. Party*& party = *partyPtr;
  12147. party->disband();
  12148. party = nullptr;
  12149. pushBoolean(L, true);
  12150. } else {
  12151. lua_pushnil(L);
  12152. }
  12153. return 1;
  12154. }
  12155.  
  12156. int LuaScriptInterface::luaPartyGetLeader(lua_State* L)
  12157. {
  12158. // party:getLeader()
  12159. Party* party = getUserdata<Party>(L, 1);
  12160. if (!party) {
  12161. lua_pushnil(L);
  12162. return 1;
  12163. }
  12164.  
  12165. Player* leader = party->getLeader();
  12166. if (leader) {
  12167. pushUserdata<Player>(L, leader);
  12168. setMetatable(L, -1, "Player");
  12169. } else {
  12170. lua_pushnil(L);
  12171. }
  12172. return 1;
  12173. }
  12174.  
  12175. int LuaScriptInterface::luaPartySetLeader(lua_State* L)
  12176. {
  12177. // party:setLeader(player)
  12178. Player* player = getPlayer(L, 2);
  12179. Party* party = getUserdata<Party>(L, 1);
  12180. if (party && player) {
  12181. pushBoolean(L, party->passPartyLeadership(player));
  12182. } else {
  12183. lua_pushnil(L);
  12184. }
  12185. return 1;
  12186. }
  12187.  
  12188. int LuaScriptInterface::luaPartyGetMembers(lua_State* L)
  12189. {
  12190. // party:getMembers()
  12191. Party* party = getUserdata<Party>(L, 1);
  12192. if (!party) {
  12193. lua_pushnil(L);
  12194. return 1;
  12195. }
  12196.  
  12197. int index = 0;
  12198. lua_createtable(L, party->getMemberCount(), 0);
  12199. for (Player* player : party->getMembers()) {
  12200. pushUserdata<Player>(L, player);
  12201. setMetatable(L, -1, "Player");
  12202. lua_rawseti(L, -2, ++index);
  12203. }
  12204. return 1;
  12205. }
  12206.  
  12207. int LuaScriptInterface::luaPartyGetMemberCount(lua_State* L)
  12208. {
  12209. // party:getMemberCount()
  12210. Party* party = getUserdata<Party>(L, 1);
  12211. if (party) {
  12212. lua_pushnumber(L, party->getMemberCount());
  12213. } else {
  12214. lua_pushnil(L);
  12215. }
  12216. return 1;
  12217. }
  12218.  
  12219. int LuaScriptInterface::luaPartyGetInvitees(lua_State* L)
  12220. {
  12221. // party:getInvitees()
  12222. Party* party = getUserdata<Party>(L, 1);
  12223. if (party) {
  12224. lua_createtable(L, party->getInvitationCount(), 0);
  12225.  
  12226. int index = 0;
  12227. for (Player* player : party->getInvitees()) {
  12228. pushUserdata<Player>(L, player);
  12229. setMetatable(L, -1, "Player");
  12230. lua_rawseti(L, -2, ++index);
  12231. }
  12232. } else {
  12233. lua_pushnil(L);
  12234. }
  12235. return 1;
  12236. }
  12237.  
  12238. int LuaScriptInterface::luaPartyGetInviteeCount(lua_State* L)
  12239. {
  12240. // party:getInviteeCount()
  12241. Party* party = getUserdata<Party>(L, 1);
  12242. if (party) {
  12243. lua_pushnumber(L, party->getInvitationCount());
  12244. } else {
  12245. lua_pushnil(L);
  12246. }
  12247. return 1;
  12248. }
  12249.  
  12250. int LuaScriptInterface::luaPartyAddInvite(lua_State* L)
  12251. {
  12252. // party:addInvite(player)
  12253. Player* player = getPlayer(L, 2);
  12254. Party* party = getUserdata<Party>(L, 1);
  12255. if (party && player) {
  12256. pushBoolean(L, party->invitePlayer(*player));
  12257. } else {
  12258. lua_pushnil(L);
  12259. }
  12260. return 1;
  12261. }
  12262.  
  12263. int LuaScriptInterface::luaPartyRemoveInvite(lua_State* L)
  12264. {
  12265. // party:removeInvite(player)
  12266. Player* player = getPlayer(L, 2);
  12267. Party* party = getUserdata<Party>(L, 1);
  12268. if (party && player) {
  12269. pushBoolean(L, party->removeInvite(*player));
  12270. } else {
  12271. lua_pushnil(L);
  12272. }
  12273. return 1;
  12274. }
  12275.  
  12276. int LuaScriptInterface::luaPartyAddMember(lua_State* L)
  12277. {
  12278. // party:addMember(player)
  12279. Player* player = getPlayer(L, 2);
  12280. Party* party = getUserdata<Party>(L, 1);
  12281. if (party && player) {
  12282. pushBoolean(L, party->joinParty(*player));
  12283. } else {
  12284. lua_pushnil(L);
  12285. }
  12286. return 1;
  12287. }
  12288.  
  12289. int LuaScriptInterface::luaPartyRemoveMember(lua_State* L)
  12290. {
  12291. // party:removeMember(player)
  12292. Player* player = getPlayer(L, 2);
  12293. Party* party = getUserdata<Party>(L, 1);
  12294. if (party && player) {
  12295. pushBoolean(L, party->leaveParty(player));
  12296. } else {
  12297. lua_pushnil(L);
  12298. }
  12299. return 1;
  12300. }
  12301.  
  12302. int LuaScriptInterface::luaPartyIsSharedExperienceActive(lua_State* L)
  12303. {
  12304. // party:isSharedExperienceActive()
  12305. Party* party = getUserdata<Party>(L, 1);
  12306. if (party) {
  12307. pushBoolean(L, party->isSharedExperienceActive());
  12308. } else {
  12309. lua_pushnil(L);
  12310. }
  12311. return 1;
  12312. }
  12313.  
  12314. int LuaScriptInterface::luaPartyIsSharedExperienceEnabled(lua_State* L)
  12315. {
  12316. // party:isSharedExperienceEnabled()
  12317. Party* party = getUserdata<Party>(L, 1);
  12318. if (party) {
  12319. pushBoolean(L, party->isSharedExperienceEnabled());
  12320. } else {
  12321. lua_pushnil(L);
  12322. }
  12323. return 1;
  12324. }
  12325.  
  12326. int LuaScriptInterface::luaPartyShareExperience(lua_State* L)
  12327. {
  12328. // party:shareExperience(experience)
  12329. uint64_t experience = getNumber<uint64_t>(L, 2);
  12330. Party* party = getUserdata<Party>(L, 1);
  12331. if (party) {
  12332. party->shareExperience(experience);
  12333. pushBoolean(L, true);
  12334. } else {
  12335. lua_pushnil(L);
  12336. }
  12337. return 1;
  12338. }
  12339.  
  12340. int LuaScriptInterface::luaPartySetSharedExperience(lua_State* L)
  12341. {
  12342. // party:setSharedExperience(active)
  12343. bool active = getBoolean(L, 2);
  12344. Party* party = getUserdata<Party>(L, 1);
  12345. if (party) {
  12346. pushBoolean(L, party->setSharedExperience(party->getLeader(), active));
  12347. } else {
  12348. lua_pushnil(L);
  12349. }
  12350. return 1;
  12351. }
  12352.  
  12353. int LuaScriptInterface::luaStoreOfferCreate(lua_State* L)
  12354. {
  12355. // StoreOffer(id)
  12356. if (isNumber(L, 2)) {
  12357. auto offer = g_store->getOfferById(getNumber<uint32_t>(L, 2));
  12358. if (offer) {
  12359. pushUserdata<StoreOffer>(L, &(*offer));
  12360. setMetatable(L, -1, "StoreOffer");
  12361. return 1;
  12362. }
  12363. }
  12364.  
  12365. lua_pushnil(L);
  12366. return 1;
  12367. }
  12368.  
  12369. int LuaScriptInterface::luaStoreOfferGetId(lua_State* L)
  12370. {
  12371. StoreOffer* offer = getUserdata<StoreOffer>(L, 1);
  12372. if (offer) {
  12373. lua_pushnumber(L, offer->id);
  12374. } else {
  12375. lua_pushnil(L);
  12376. }
  12377. return 1;
  12378. }
  12379.  
  12380. int LuaScriptInterface::luaStoreOfferGetName(lua_State* L)
  12381. {
  12382. // storeOffer:getName()
  12383. StoreOffer* offer = getUserdata<StoreOffer>(L, 1);
  12384. if (offer) {
  12385. pushString(L, offer->name);
  12386. } else {
  12387. lua_pushnil(L);
  12388. }
  12389. return 1;
  12390. }
  12391.  
  12392. //
  12393. LuaEnvironment::LuaEnvironment() :
  12394. LuaScriptInterface("Main Interface"), m_testInterface(nullptr),
  12395. m_lastEventTimerId(1), m_lastCombatId(0), m_lastAreaId(0)
  12396. {
  12397. //
  12398. }
  12399.  
  12400. LuaEnvironment::~LuaEnvironment()
  12401. {
  12402. delete m_testInterface;
  12403. closeState();
  12404. }
  12405.  
  12406. bool LuaEnvironment::initState()
  12407. {
  12408. m_luaState = luaL_newstate();
  12409. if (!m_luaState) {
  12410. return false;
  12411. }
  12412.  
  12413. luaL_openlibs(m_luaState);
  12414. registerFunctions();
  12415.  
  12416. m_runningEventId = EVENT_ID_USER;
  12417. return true;
  12418. }
  12419.  
  12420. bool LuaEnvironment::reInitState()
  12421. {
  12422. // TODO: get children, reload children
  12423. closeState();
  12424. return initState();
  12425. }
  12426.  
  12427. bool LuaEnvironment::closeState()
  12428. {
  12429. if (!m_luaState) {
  12430. return false;
  12431. }
  12432.  
  12433. for (const auto& combatEntry : m_combatIdMap) {
  12434. clearCombatObjects(combatEntry.first);
  12435. }
  12436.  
  12437. for (const auto& areaEntry : m_areaIdMap) {
  12438. clearAreaObjects(areaEntry.first);
  12439. }
  12440.  
  12441. for (auto& timerEntry : m_timerEvents) {
  12442. LuaTimerEventDesc timerEventDesc = std::move(timerEntry.second);
  12443. for (int32_t parameter : timerEventDesc.parameters) {
  12444. luaL_unref(m_luaState, LUA_REGISTRYINDEX, parameter);
  12445. }
  12446. luaL_unref(m_luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
  12447. }
  12448.  
  12449. m_combatIdMap.clear();
  12450. m_areaIdMap.clear();
  12451. m_timerEvents.clear();
  12452. m_cacheFiles.clear();
  12453.  
  12454. lua_close(m_luaState);
  12455. m_luaState = nullptr;
  12456. return true;
  12457. }
  12458.  
  12459. LuaScriptInterface* LuaEnvironment::getTestInterface()
  12460. {
  12461. if (!m_testInterface) {
  12462. m_testInterface = new LuaScriptInterface("Test Interface");
  12463. m_testInterface->initState();
  12464. }
  12465. return m_testInterface;
  12466. }
  12467.  
  12468. Combat* LuaEnvironment::getCombatObject(uint32_t id) const
  12469. {
  12470. auto it = m_combatMap.find(id);
  12471. if (it == m_combatMap.end()) {
  12472. return nullptr;
  12473. }
  12474. return it->second;
  12475. }
  12476.  
  12477. Combat* LuaEnvironment::createCombatObject(LuaScriptInterface* interface)
  12478. {
  12479. Combat* combat = new Combat;
  12480. m_combatMap[++m_lastCombatId] = combat;
  12481. m_combatIdMap[interface].push_back(m_lastCombatId);
  12482. return combat;
  12483. }
  12484.  
  12485. void LuaEnvironment::clearCombatObjects(LuaScriptInterface* interface)
  12486. {
  12487. auto it = m_combatIdMap.find(interface);
  12488. if (it == m_combatIdMap.end()) {
  12489. return;
  12490. }
  12491.  
  12492. for (uint32_t id : it->second) {
  12493. auto itt = m_combatMap.find(id);
  12494. if (itt != m_combatMap.end()) {
  12495. delete itt->second;
  12496. m_combatMap.erase(itt);
  12497. }
  12498. }
  12499. it->second.clear();
  12500. }
  12501.  
  12502. AreaCombat* LuaEnvironment::getAreaObject(uint32_t id) const
  12503. {
  12504. auto it = m_areaMap.find(id);
  12505. if (it == m_areaMap.end()) {
  12506. return nullptr;
  12507. }
  12508. return it->second;
  12509. }
  12510.  
  12511. uint32_t LuaEnvironment::createAreaObject(LuaScriptInterface* interface)
  12512. {
  12513. m_areaMap[++m_lastAreaId] = new AreaCombat;
  12514. m_areaIdMap[interface].push_back(m_lastAreaId);
  12515. return m_lastAreaId;
  12516. }
  12517.  
  12518. void LuaEnvironment::clearAreaObjects(LuaScriptInterface* interface)
  12519. {
  12520. auto it = m_areaIdMap.find(interface);
  12521. if (it == m_areaIdMap.end()) {
  12522. return;
  12523. }
  12524.  
  12525. for (uint32_t id : it->second) {
  12526. auto itt = m_areaMap.find(id);
  12527. if (itt != m_areaMap.end()) {
  12528. delete itt->second;
  12529. m_areaMap.erase(itt);
  12530. }
  12531. }
  12532. it->second.clear();
  12533. }
  12534.  
  12535. void LuaEnvironment::executeTimerEvent(uint32_t eventIndex)
  12536. {
  12537. auto it = m_timerEvents.find(eventIndex);
  12538. if (it == m_timerEvents.end()) {
  12539. return;
  12540. }
  12541.  
  12542. LuaTimerEventDesc timerEventDesc = std::move(it->second);
  12543. m_timerEvents.erase(it);
  12544.  
  12545. //push function
  12546. lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
  12547.  
  12548. //push parameters
  12549. for (auto parameter : boost::adaptors::reverse(timerEventDesc.parameters)) {
  12550. lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, parameter);
  12551. }
  12552.  
  12553. //call the function
  12554. if (reserveScriptEnv()) {
  12555. ScriptEnvironment* env = getScriptEnv();
  12556. env->setTimerEvent();
  12557. env->setScriptId(timerEventDesc.scriptId, this);
  12558. callFunction(timerEventDesc.parameters.size());
  12559. } else {
  12560. std::cout << "[Error - LuaScriptInterface::executeTimerEvent] Call stack overflow" << std::endl;
  12561. }
  12562.  
  12563. //free resources
  12564. luaL_unref(m_luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
  12565. for (auto parameter : timerEventDesc.parameters) {
  12566. luaL_unref(m_luaState, LUA_REGISTRYINDEX, parameter);
  12567. }
  12568. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement