Advertisement
Guest User

Movement.cpp

a guest
Nov 24th, 2018
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 37.81 KB | None | 0 0
  1. ////////////////////////////////////////////////////////////////////////
  2. // OpenTibia - an opensource roleplaying game
  3. ////////////////////////////////////////////////////////////////////////
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ////////////////////////////////////////////////////////////////////////
  17. #include "otpch.h"
  18. #include <libxml/xmlmemory.h>
  19. #include <libxml/parser.h>
  20.  
  21. #include "movement.h"
  22. #include "tools.h"
  23.  
  24. #include "creature.h"
  25. #include "player.h"
  26.  
  27. #include "tile.h"
  28. #include "vocation.h"
  29.  
  30. #include "combat.h"
  31. #include "game.h"
  32.  
  33. extern Game g_game;
  34. extern MoveEvents* g_moveEvents;
  35.  
  36. MoveEvent* MoveEventScript::event = NULL;
  37.  
  38. void MoveEventScript::registerFunctions()
  39. {
  40. LuaInterface::registerFunctions();
  41. lua_register(m_luaState, "callFunction", MoveEventScript::luaCallFunction);
  42. }
  43.  
  44. int32_t MoveEventScript::luaCallFunction(lua_State* L)
  45. {
  46. //callFunction(...)
  47. MoveEvent* event = MoveEventScript::event;
  48. if(!event)
  49. {
  50. error(__FUNCTION__, "MoveEvent not set!");
  51. lua_pushboolean(L, false);
  52. return 1;
  53. }
  54.  
  55. if(event->getEventType() == MOVE_EVENT_EQUIP || event->getEventType() == MOVE_EVENT_DE_EQUIP)
  56. {
  57. ScriptEnviroment* env = getEnv();
  58. bool boolean = popNumber(L);
  59. slots_t slot = (slots_t)popNumber(L);
  60.  
  61. Item* item = env->getItemByUID(popNumber(L));
  62. if(!item)
  63. {
  64. error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND));
  65. lua_pushboolean(L, false);
  66. return 1;
  67. }
  68.  
  69. Player* player = env->getPlayerByUID(popNumber(L));
  70. if(!player)
  71. {
  72. error(__FUNCTION__, getError(LUA_ERROR_PLAYER_NOT_FOUND));
  73. lua_pushboolean(L, false);
  74. return 1;
  75. }
  76.  
  77. if(event->getEventType() != MOVE_EVENT_EQUIP)
  78. lua_pushboolean(L, MoveEvent::DeEquipItem(event, player, item, slot, boolean));
  79. else
  80. lua_pushboolean(L, MoveEvent::EquipItem(event, player, item, slot, boolean));
  81.  
  82. return 1;
  83. }
  84. else if(event->getEventType() == MOVE_EVENT_STEP_IN)
  85. {
  86. ScriptEnviroment* env = getEnv();
  87. Item* item = env->getItemByUID(popNumber(L));
  88. if(!item)
  89. {
  90. error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND));
  91. lua_pushboolean(L, false);
  92. return 1;
  93. }
  94.  
  95. Creature* creature = env->getCreatureByUID(popNumber(L));
  96. if(!creature)
  97. {
  98. error(__FUNCTION__, getError(LUA_ERROR_CREATURE_NOT_FOUND));
  99. lua_pushboolean(L, false);
  100. return 1;
  101. }
  102.  
  103. lua_pushboolean(L, MoveEvent::StepInField(creature, item));
  104. return 1;
  105. }
  106. else if(event->getEventType() == MOVE_EVENT_ADD_ITEM)
  107. {
  108. ScriptEnviroment* env = getEnv();
  109. Item* item = env->getItemByUID(popNumber(L));
  110. if(!item)
  111. {
  112. error(__FUNCTION__, getError(LUA_ERROR_ITEM_NOT_FOUND));
  113. lua_pushboolean(L, false);
  114. return 1;
  115. }
  116.  
  117. lua_pushboolean(L, MoveEvent::AddItemField(item));
  118. return 1;
  119. }
  120.  
  121. error(__FUNCTION__, "callFunction not available for current event.");
  122. lua_pushboolean(L, false);
  123. return 1;
  124. }
  125.  
  126. MoveEvents::MoveEvents():
  127. m_lastCacheTile(NULL)
  128. {
  129. m_interface.initState();
  130. }
  131.  
  132. inline void MoveEvents::clearMap(MoveListMap& map)
  133. {
  134. for(MoveListMap::iterator it = map.begin(); it != map.end(); ++it)
  135. {
  136. for(int32_t i = MOVE_EVENT_FIRST; i <= MOVE_EVENT_LAST; ++i)
  137. {
  138. EventList& moveEventList = it->second.moveEvent[i];
  139. for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it)
  140. delete (*it);
  141.  
  142. moveEventList.clear();
  143. }
  144. }
  145.  
  146. map.clear();
  147. }
  148.  
  149. void MoveEvents::clear()
  150. {
  151. clearMap(m_itemIdMap);
  152. clearMap(m_actionIdMap);
  153. clearMap(m_uniqueIdMap);
  154.  
  155. for(MovePosListMap::iterator it = m_positionMap.begin(); it != m_positionMap.end(); ++it)
  156. {
  157. for(int32_t i = MOVE_EVENT_FIRST; i <= MOVE_EVENT_LAST; ++i)
  158. {
  159. EventList& moveEventList = it->second.moveEvent[i];
  160. for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it)
  161. delete (*it);
  162.  
  163. moveEventList.clear();
  164. }
  165. }
  166.  
  167. m_positionMap.clear();
  168. m_interface.reInitState();
  169.  
  170. m_lastCacheTile = NULL;
  171. m_lastCacheItemVector.clear();
  172. }
  173.  
  174. Event* MoveEvents::getEvent(const std::string& nodeName)
  175. {
  176. std::string tmpNodeName = asLowerCaseString(nodeName);
  177. if(tmpNodeName == "movevent" || tmpNodeName == "moveevent" || tmpNodeName == "movement")
  178. return new MoveEvent(&m_interface);
  179.  
  180. return NULL;
  181. }
  182.  
  183. bool MoveEvents::registerEvent(Event* event, xmlNodePtr p, bool override)
  184. {
  185. MoveEvent* moveEvent = dynamic_cast<MoveEvent*>(event);
  186. if(!moveEvent)
  187. return false;
  188.  
  189. std::string strValue, endStrValue;
  190. MoveEvent_t eventType = moveEvent->getEventType();
  191. if((eventType == MOVE_EVENT_ADD_ITEM || eventType == MOVE_EVENT_REMOVE_ITEM) &&
  192. readXMLString(p, "tileitem", strValue) && booleanString(strValue))
  193. {
  194. switch(eventType)
  195. {
  196. case MOVE_EVENT_ADD_ITEM:
  197. moveEvent->setEventType(MOVE_EVENT_ADD_TILEITEM);
  198. break;
  199. case MOVE_EVENT_REMOVE_ITEM:
  200. moveEvent->setEventType(MOVE_EVENT_REMOVE_TILEITEM);
  201. break;
  202. default:
  203. break;
  204. }
  205. }
  206.  
  207. StringVec strVector;
  208. IntegerVec intVector, endIntVector;
  209.  
  210. bool success = true;
  211. if(readXMLString(p, "itemid", strValue))
  212. {
  213. strVector = explodeString(strValue, ";");
  214. for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it)
  215. {
  216. intVector = vectorAtoi(explodeString((*it), "-"));
  217. if(!intVector[0])
  218. continue;
  219.  
  220. bool equip = moveEvent->getEventType() == MOVE_EVENT_EQUIP;
  221. addEvent(moveEvent, intVector[0], m_itemIdMap, override);
  222. if(equip)
  223. {
  224. ItemType& it = Item::items.getItemType(intVector[0]);
  225. it.wieldInfo = moveEvent->getWieldInfo();
  226. it.minReqLevel = moveEvent->getReqLevel();
  227. it.minReqMagicLevel = moveEvent->getReqMagLv();
  228. it.vocationString = moveEvent->getVocationString();
  229. }
  230.  
  231. if(intVector.size() > 1)
  232. {
  233. while(intVector[0] < intVector[1])
  234. {
  235. addEvent(new MoveEvent(moveEvent), ++intVector[0], m_itemIdMap, override);
  236. if(equip)
  237. {
  238. ItemType& tit = Item::items.getItemType(intVector[0]);
  239. tit.wieldInfo = moveEvent->getWieldInfo();
  240. tit.minReqLevel = moveEvent->getReqLevel();
  241. tit.minReqMagicLevel = moveEvent->getReqMagLv();
  242. tit.vocationString = moveEvent->getVocationString();
  243. }
  244. }
  245. }
  246. }
  247. }
  248.  
  249. if(readXMLString(p, "fromid", strValue) && readXMLString(p, "toid", endStrValue))
  250. {
  251. intVector = vectorAtoi(explodeString(strValue, ";"));
  252. endIntVector = vectorAtoi(explodeString(endStrValue, ";"));
  253. if(intVector[0] && endIntVector[0] && intVector.size() == endIntVector.size())
  254. {
  255. for(size_t i = 0, size = intVector.size(); i < size; ++i)
  256. {
  257. bool equip = moveEvent->getEventType() == MOVE_EVENT_EQUIP;
  258. addEvent(moveEvent, intVector[i], m_itemIdMap, override);
  259. if(equip)
  260. {
  261. ItemType& it = Item::items.getItemType(intVector[i]);
  262. it.wieldInfo = moveEvent->getWieldInfo();
  263. it.minReqLevel = moveEvent->getReqLevel();
  264. it.minReqMagicLevel = moveEvent->getReqMagLv();
  265. it.vocationString = moveEvent->getVocationString();
  266. }
  267.  
  268. while(intVector[i] < endIntVector[i])
  269. {
  270. addEvent(new MoveEvent(moveEvent), ++intVector[i], m_itemIdMap, override);
  271. if(equip)
  272. {
  273. ItemType& tit = Item::items.getItemType(intVector[i]);
  274. tit.wieldInfo = moveEvent->getWieldInfo();
  275. tit.minReqLevel = moveEvent->getReqLevel();
  276. tit.minReqMagicLevel = moveEvent->getReqMagLv();
  277. tit.vocationString = moveEvent->getVocationString();
  278. }
  279. }
  280. }
  281. }
  282. else
  283. std::clog << "[Warning - MoveEvents::registerEvent] Malformed entry (from item: \"" << strValue << "\", to item: \"" << endStrValue << "\")" << std::endl;
  284. }
  285.  
  286. if(readXMLString(p, "uniqueid", strValue))
  287. {
  288. strVector = explodeString(strValue, ";");
  289. for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it)
  290. {
  291. intVector = vectorAtoi(explodeString((*it), "-"));
  292. if(!intVector[0])
  293. continue;
  294.  
  295. addEvent(moveEvent, intVector[0], m_uniqueIdMap, override);
  296. if(intVector.size() > 1)
  297. {
  298. while(intVector[0] < intVector[1])
  299. addEvent(new MoveEvent(moveEvent), ++intVector[0], m_uniqueIdMap, override);
  300. }
  301. }
  302. }
  303.  
  304. if(readXMLString(p, "fromuid", strValue) && readXMLString(p, "touid", endStrValue))
  305. {
  306. intVector = vectorAtoi(explodeString(strValue, ";"));
  307. endIntVector = vectorAtoi(explodeString(endStrValue, ";"));
  308. if(intVector[0] && endIntVector[0] && intVector.size() == endIntVector.size())
  309. {
  310. for(size_t i = 0, size = intVector.size(); i < size; ++i)
  311. {
  312. addEvent(moveEvent, intVector[i], m_uniqueIdMap, override);
  313. while(intVector[i] < endIntVector[i])
  314. addEvent(new MoveEvent(moveEvent), ++intVector[i], m_uniqueIdMap, override);
  315. }
  316. }
  317. else
  318. std::clog << "[Warning - MoveEvents::registerEvent] Malformed entry (from unique: \"" << strValue << "\", to unique: \"" << endStrValue << "\")" << std::endl;
  319. }
  320.  
  321. if(readXMLString(p, "actionid", strValue))
  322. {
  323. strVector = explodeString(strValue, ";");
  324. for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it)
  325. {
  326. intVector = vectorAtoi(explodeString((*it), "-"));
  327. if(!intVector[0])
  328. continue;
  329.  
  330. addEvent(moveEvent, intVector[0], m_actionIdMap, override);
  331. if(intVector.size() > 1)
  332. {
  333. while(intVector[0] < intVector[1])
  334. addEvent(new MoveEvent(moveEvent), ++intVector[0], m_actionIdMap, override);
  335. }
  336. }
  337. }
  338.  
  339. if(readXMLString(p, "fromaid", strValue) && readXMLString(p, "toaid", endStrValue))
  340. {
  341. intVector = vectorAtoi(explodeString(strValue, ";"));
  342. endIntVector = vectorAtoi(explodeString(endStrValue, ";"));
  343. if(intVector[0] && endIntVector[0] && intVector.size() == endIntVector.size())
  344. {
  345. for(size_t i = 0, size = intVector.size(); i < size; ++i)
  346. {
  347. addEvent(moveEvent, intVector[i], m_actionIdMap, override);
  348. while(intVector[i] < endIntVector[i])
  349. addEvent(new MoveEvent(moveEvent), ++intVector[i], m_actionIdMap, override);
  350. }
  351. }
  352. else
  353. std::clog << "[Warning - MoveEvents::registerEvent] Malformed entry (from action: \"" << strValue << "\", to action: \"" << endStrValue << "\")" << std::endl;
  354. }
  355.  
  356. if(readXMLString(p, "pos", strValue) || readXMLString(p, "position", strValue))
  357. {
  358. strVector = explodeString(strValue, ";");
  359. for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it)
  360. {
  361. intVector = vectorAtoi(explodeString((*it), ","));
  362. if(intVector.size() > 2)
  363. addEvent(moveEvent, Position(intVector[0], intVector[1], intVector[2]), m_positionMap, override);
  364. else
  365. success = false;
  366. }
  367. }
  368.  
  369. return success;
  370. }
  371.  
  372. void MoveEvents::addEvent(MoveEvent* moveEvent, int32_t id, MoveListMap& map, bool override)
  373. {
  374. MoveListMap::iterator it = map.find(id);
  375. if(it != map.end())
  376. {
  377. EventList& moveEventList = it->second.moveEvent[moveEvent->getEventType()];
  378. for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it)
  379. {
  380. if((*it)->getSlot() != moveEvent->getSlot())
  381. continue;
  382.  
  383. if(override)
  384. {
  385. delete *it;
  386. *it = moveEvent;
  387. }
  388. else
  389. std::clog << "[Warning - MoveEvents::addEvent] Duplicate move event found: " << id << std::endl;
  390.  
  391. return;
  392. }
  393.  
  394. moveEventList.push_back(moveEvent);
  395. }
  396. else
  397. {
  398. MoveEventList moveEventList;
  399. moveEventList.moveEvent[moveEvent->getEventType()].push_back(moveEvent);
  400. map[id] = moveEventList;
  401. }
  402. }
  403.  
  404. MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType)
  405. {
  406. MoveListMap::iterator it;
  407. if(item->getUniqueId())
  408. {
  409. it = m_uniqueIdMap.find(item->getUniqueId());
  410. if(it != m_uniqueIdMap.end())
  411. {
  412. EventList& moveEventList = it->second.moveEvent[eventType];
  413. if(!moveEventList.empty())
  414. return *moveEventList.begin();
  415. }
  416. }
  417.  
  418. if(item->getActionId())
  419. {
  420. it = m_actionIdMap.find(item->getActionId());
  421. if(it != m_actionIdMap.end())
  422. {
  423. EventList& moveEventList = it->second.moveEvent[eventType];
  424. if(!moveEventList.empty())
  425. return *moveEventList.begin();
  426. }
  427. }
  428.  
  429. it = m_itemIdMap.find(item->getID());
  430. if(it != m_itemIdMap.end())
  431. {
  432. EventList& moveEventList = it->second.moveEvent[eventType];
  433. if(!moveEventList.empty())
  434. return *moveEventList.begin();
  435. }
  436.  
  437. return NULL;
  438. }
  439.  
  440. MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType, slots_t slot)
  441. {
  442. uint32_t slotp = 0;
  443. switch(slot)
  444. {
  445. case SLOT_HEAD:
  446. slotp = SLOTP_HEAD;
  447. break;
  448. case SLOT_NECKLACE:
  449. slotp = SLOTP_NECKLACE;
  450. break;
  451. case SLOT_BACKPACK:
  452. slotp = SLOTP_BACKPACK;
  453. break;
  454. case SLOT_ARMOR:
  455. slotp = SLOTP_ARMOR;
  456. break;
  457. case SLOT_RIGHT:
  458. slotp = SLOTP_RIGHT;
  459. break;
  460. case SLOT_LEFT:
  461. slotp = SLOTP_LEFT;
  462. break;
  463. case SLOT_LEGS:
  464. slotp = SLOTP_LEGS;
  465. break;
  466. case SLOT_FEET:
  467. slotp = SLOTP_FEET;
  468. break;
  469. case SLOT_AMMO:
  470. slotp = SLOTP_AMMO;
  471. break;
  472. case SLOT_RING:
  473. slotp = SLOTP_RING;
  474. break;
  475. default:
  476. break;
  477. }
  478.  
  479. MoveListMap::iterator it = m_itemIdMap.find(item->getID());
  480. if(it == m_itemIdMap.end())
  481. return NULL;
  482.  
  483. EventList& moveEventList = it->second.moveEvent[eventType];
  484. for(EventList::iterator it = moveEventList.begin(); it != moveEventList.end(); ++it)
  485. {
  486. if(((*it)->getSlot() & slotp))
  487. return *it;
  488. }
  489.  
  490. return NULL;
  491. }
  492.  
  493. void MoveEvents::addEvent(MoveEvent* moveEvent, Position pos, MovePosListMap& map, bool override)
  494. {
  495. MovePosListMap::iterator it = map.find(pos);
  496. if(it != map.end())
  497. {
  498. bool add = true;
  499. if(!it->second.moveEvent[moveEvent->getEventType()].empty())
  500. {
  501. if(!override)
  502. {
  503. std::clog << "[Warning - MoveEvents::addEvent] Duplicate move event found: " << pos << std::endl;
  504. add = false;
  505. }
  506. else
  507. it->second.moveEvent[moveEvent->getEventType()].clear();
  508. }
  509.  
  510. if(add)
  511. it->second.moveEvent[moveEvent->getEventType()].push_back(moveEvent);
  512. }
  513. else
  514. {
  515. MoveEventList moveEventList;
  516. moveEventList.moveEvent[moveEvent->getEventType()].push_back(moveEvent);
  517. map[pos] = moveEventList;
  518. }
  519. }
  520.  
  521. MoveEvent* MoveEvents::getEvent(const Tile* tile, MoveEvent_t eventType)
  522. {
  523. MovePosListMap::iterator it = m_positionMap.find(tile->getPosition());
  524. if(it == m_positionMap.end())
  525. return NULL;
  526.  
  527. EventList& moveEventList = it->second.moveEvent[eventType];
  528. if(!moveEventList.empty())
  529. return *moveEventList.begin();
  530.  
  531. return NULL;
  532. }
  533.  
  534. bool MoveEvents::hasEquipEvent(Item* item)
  535. {
  536. return getEvent(item, MOVE_EVENT_EQUIP) && getEvent(item, MOVE_EVENT_DE_EQUIP);
  537. }
  538.  
  539. bool MoveEvents::hasTileEvent(Item* item)
  540. {
  541. return getEvent(item, MOVE_EVENT_STEP_IN) || getEvent(item, MOVE_EVENT_STEP_OUT) || getEvent(
  542. item, MOVE_EVENT_ADD_TILEITEM) || getEvent(item, MOVE_EVENT_REMOVE_TILEITEM);
  543. }
  544.  
  545. uint32_t MoveEvents::onCreatureMove(Creature* actor, Creature* creature, const Tile* fromTile, const Tile* toTile, bool isStepping)
  546. {
  547. MoveEvent_t eventType = MOVE_EVENT_STEP_OUT;
  548. const Tile* tile = fromTile;
  549. if(isStepping)
  550. {
  551. eventType = MOVE_EVENT_STEP_IN;
  552. tile = toTile;
  553. }
  554.  
  555. Position fromPos;
  556. if(fromTile)
  557. fromPos = fromTile->getPosition();
  558.  
  559. Position toPos;
  560. if(toTile)
  561. toPos = toTile->getPosition();
  562.  
  563. uint32_t ret = 1;
  564. MoveEvent* moveEvent = NULL;
  565. if((moveEvent = getEvent(tile, eventType)))
  566. ret &= moveEvent->fireStepEvent(actor, creature, NULL, Position(), fromPos, toPos);
  567.  
  568. Item* tileItem = NULL;
  569. if(m_lastCacheTile == tile)
  570. {
  571. if(m_lastCacheItemVector.empty())
  572. return ret;
  573.  
  574. //We cannot use iterators here since the scripts can invalidate the iterator
  575. for(uint32_t i = 0; i < m_lastCacheItemVector.size(); ++i)
  576. {
  577. if((tileItem = m_lastCacheItemVector[i]) && (moveEvent = getEvent(tileItem, eventType)))
  578. ret &= moveEvent->fireStepEvent(actor, creature, tileItem, tile->getPosition(), fromPos, toPos);
  579. }
  580.  
  581. return ret;
  582. }
  583.  
  584. m_lastCacheTile = tile;
  585. m_lastCacheItemVector.clear();
  586.  
  587. //We cannot use iterators here since the scripts can invalidate the iterator
  588. Thing* thing = NULL;
  589. for(int32_t i = tile->__getFirstIndex(); i < tile->__getLastIndex(); ++i) //already checked the ground
  590. {
  591. if(!(thing = tile->__getThing(i)) || !(tileItem = thing->getItem()))
  592. continue;
  593.  
  594. if((moveEvent = getEvent(tileItem, eventType)))
  595. {
  596. m_lastCacheItemVector.push_back(tileItem);
  597. ret &= moveEvent->fireStepEvent(actor, creature, tileItem, tile->getPosition(), fromPos, toPos);
  598. }
  599. else if(hasTileEvent(tileItem))
  600. m_lastCacheItemVector.push_back(tileItem);
  601. }
  602.  
  603. return ret;
  604. }
  605.  
  606. bool MoveEvents::onPlayerEquip(Player* player, Item* item, slots_t slot, bool isCheck)
  607. {
  608. if(MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_EQUIP, slot))
  609. return moveEvent->fireEquip(player, item, slot, isCheck);
  610.  
  611. return true;
  612. }
  613.  
  614. bool MoveEvents::onPlayerDeEquip(Player* player, Item* item, slots_t slot, bool isRemoval)
  615. {
  616. if(MoveEvent* moveEvent = getEvent(item, MOVE_EVENT_DE_EQUIP, slot))
  617. return moveEvent->fireEquip(player, item, slot, isRemoval);
  618.  
  619. return true;
  620. }
  621.  
  622. uint32_t MoveEvents::onItemMove(Creature* actor, Item* item, Tile* tile, bool isAdd)
  623. {
  624. MoveEvent_t eventType = MOVE_EVENT_REMOVE_ITEM, tileEventType = MOVE_EVENT_REMOVE_TILEITEM;
  625. if(isAdd)
  626. {
  627. eventType = MOVE_EVENT_ADD_ITEM;
  628. tileEventType = MOVE_EVENT_ADD_TILEITEM;
  629. }
  630.  
  631. uint32_t ret = 1;
  632. MoveEvent* moveEvent = getEvent(tile, eventType);
  633. if(moveEvent)
  634. ret &= moveEvent->fireAddRemItem(actor, item, NULL, tile->getPosition());
  635.  
  636. moveEvent = getEvent(item, eventType);
  637. if(moveEvent)
  638. ret &= moveEvent->fireAddRemItem(actor, item, NULL, tile->getPosition());
  639.  
  640. Item* tileItem = NULL;
  641. if(m_lastCacheTile == tile)
  642. {
  643. if(m_lastCacheItemVector.empty())
  644. return ret;
  645.  
  646. //We cannot use iterators here since the scripts can invalidate the iterator
  647. for(uint32_t i = 0; i < m_lastCacheItemVector.size(); ++i)
  648. {
  649. if((tileItem = m_lastCacheItemVector[i]) && tileItem != item
  650. && (moveEvent = getEvent(tileItem, tileEventType)))
  651. ret &= moveEvent->fireAddRemItem(actor, item, tileItem, tile->getPosition());
  652. }
  653.  
  654. return ret;
  655. }
  656.  
  657. m_lastCacheTile = tile;
  658. m_lastCacheItemVector.clear();
  659.  
  660. //we cannot use iterators here since the scripts can invalidate the iterator
  661. Thing* thing = NULL;
  662. for(int32_t i = tile->__getFirstIndex(); i < tile->__getLastIndex(); ++i) //already checked the ground
  663. {
  664. if(!(thing = tile->__getThing(i)) || !(tileItem = thing->getItem()) || tileItem == item)
  665. continue;
  666.  
  667. if((moveEvent = getEvent(tileItem, tileEventType)))
  668. {
  669. m_lastCacheItemVector.push_back(tileItem);
  670. ret &= moveEvent->fireAddRemItem(actor, item, tileItem, tile->getPosition());
  671. }
  672. else if(hasTileEvent(tileItem))
  673. m_lastCacheItemVector.push_back(tileItem);
  674. }
  675.  
  676. return ret;
  677. }
  678.  
  679. void MoveEvents::onAddTileItem(const Tile* tile, Item* item)
  680. {
  681. if(m_lastCacheTile != tile)
  682. return;
  683.  
  684. std::vector<Item*>::iterator it = std::find(m_lastCacheItemVector.begin(), m_lastCacheItemVector.end(), item);
  685. if(it == m_lastCacheItemVector.end() && hasTileEvent(item))
  686. m_lastCacheItemVector.push_back(item);
  687. }
  688.  
  689. void MoveEvents::onRemoveTileItem(const Tile* tile, Item* item)
  690. {
  691. if(m_lastCacheTile != tile)
  692. return;
  693.  
  694. for(uint32_t i = 0; i < m_lastCacheItemVector.size(); ++i)
  695. {
  696. if(m_lastCacheItemVector[i] != item)
  697. continue;
  698.  
  699. m_lastCacheItemVector[i] = NULL;
  700. break;
  701. }
  702. }
  703.  
  704. MoveEvent::MoveEvent(LuaInterface* _interface):
  705. Event(_interface)
  706. {
  707. m_eventType = MOVE_EVENT_NONE;
  708. stepFunction = NULL;
  709. moveFunction = NULL;
  710. equipFunction = NULL;
  711. slot = SLOTP_WHEREEVER;
  712. wieldInfo = 0;
  713. reqLevel = 0;
  714. reqMagLevel = 0;
  715. premium = false;
  716. }
  717.  
  718. MoveEvent::MoveEvent(const MoveEvent* copy):
  719. Event(copy)
  720. {
  721. m_eventType = copy->m_eventType;
  722. stepFunction = copy->stepFunction;
  723. moveFunction = copy->moveFunction;
  724. equipFunction = copy->equipFunction;
  725. slot = copy->slot;
  726. if(copy->m_eventType == MOVE_EVENT_EQUIP)
  727. {
  728. wieldInfo = copy->wieldInfo;
  729. reqLevel = copy->reqLevel;
  730. reqMagLevel = copy->reqMagLevel;
  731. vocationString = copy->vocationString;
  732. premium = copy->premium;
  733. vocEquipMap = copy->vocEquipMap;
  734. }
  735. }
  736.  
  737. MoveEvent::~MoveEvent()
  738. {
  739. //
  740. }
  741.  
  742. std::string MoveEvent::getScriptEventName() const
  743. {
  744. switch(m_eventType)
  745. {
  746. case MOVE_EVENT_STEP_IN:
  747. return "onStepIn";
  748.  
  749. case MOVE_EVENT_STEP_OUT:
  750. return "onStepOut";
  751.  
  752. case MOVE_EVENT_EQUIP:
  753. return "onEquip";
  754.  
  755. case MOVE_EVENT_DE_EQUIP:
  756. return "onDeEquip";
  757.  
  758. case MOVE_EVENT_ADD_ITEM:
  759. return "onAddItem";
  760.  
  761. case MOVE_EVENT_REMOVE_ITEM:
  762. return "onRemoveItem";
  763.  
  764. default:
  765. break;
  766. }
  767.  
  768. std::clog << "[Error - MoveEvent::getScriptEventName] No valid event type." << std::endl;
  769. return "";
  770. }
  771.  
  772. std::string MoveEvent::getScriptEventParams() const
  773. {
  774. switch(m_eventType)
  775. {
  776. case MOVE_EVENT_STEP_IN:
  777. case MOVE_EVENT_STEP_OUT:
  778. return "cid, item, position, lastPosition, fromPosition, toPosition, actor";
  779.  
  780. case MOVE_EVENT_EQUIP:
  781. case MOVE_EVENT_DE_EQUIP:
  782. return "cid, item, slot, boolean";
  783.  
  784. case MOVE_EVENT_ADD_ITEM:
  785. case MOVE_EVENT_REMOVE_ITEM:
  786. return "moveItem, tileItem, position, cid";
  787.  
  788. default:
  789. break;
  790. }
  791.  
  792. std::clog << "[Error - MoveEvent::getScriptEventParams] No valid event type." << std::endl;
  793. return "";
  794. }
  795.  
  796. bool MoveEvent::configureEvent(xmlNodePtr p)
  797. {
  798. std::string strValue;
  799. int32_t intValue;
  800. if(readXMLString(p, "type", strValue) || readXMLString(p, "event", strValue))
  801. {
  802. std::string tmpStrValue = asLowerCaseString(strValue);
  803. if(tmpStrValue == "stepin")
  804. m_eventType = MOVE_EVENT_STEP_IN;
  805. else if(tmpStrValue == "stepout")
  806. m_eventType = MOVE_EVENT_STEP_OUT;
  807. else if(tmpStrValue == "equip")
  808. m_eventType = MOVE_EVENT_EQUIP;
  809. else if(tmpStrValue == "deequip")
  810. m_eventType = MOVE_EVENT_DE_EQUIP;
  811. else if(tmpStrValue == "additem")
  812. m_eventType = MOVE_EVENT_ADD_ITEM;
  813. else if(tmpStrValue == "removeitem")
  814. m_eventType = MOVE_EVENT_REMOVE_ITEM;
  815. else
  816. {
  817. std::clog << "[Error - MoveEvent::configureMoveEvent] Unknown event type \"" << strValue << "\"" << std::endl;
  818. return false;
  819. }
  820.  
  821. if(m_eventType == MOVE_EVENT_EQUIP || m_eventType == MOVE_EVENT_DE_EQUIP)
  822. {
  823. if(readXMLString(p, "slot", strValue))
  824. {
  825. std::string tmpStrValue = asLowerCaseString(strValue);
  826. if(tmpStrValue == "head")
  827. slot = SLOTP_HEAD;
  828. else if(tmpStrValue == "necklace")
  829. slot = SLOTP_NECKLACE;
  830. else if(tmpStrValue == "backpack")
  831. slot = SLOTP_BACKPACK;
  832. else if(tmpStrValue == "armor")
  833. slot = SLOTP_ARMOR;
  834. else if(tmpStrValue == "left-hand")
  835. slot = SLOTP_LEFT;
  836. else if(tmpStrValue == "right-hand")
  837. slot = SLOTP_RIGHT;
  838. else if(tmpStrValue == "hands" || tmpStrValue == "two-handed")
  839. slot = SLOTP_TWO_HAND;
  840. else if(tmpStrValue == "hand" || tmpStrValue == "shield")
  841. slot = SLOTP_RIGHT | SLOTP_LEFT;
  842. else if(tmpStrValue == "legs")
  843. slot = SLOTP_LEGS;
  844. else if(tmpStrValue == "feet")
  845. slot = SLOTP_FEET;
  846. else if(tmpStrValue == "ring")
  847. slot = SLOTP_RING;
  848. else if(tmpStrValue == "ammo" || tmpStrValue == "ammunition")
  849. slot = SLOTP_AMMO;
  850. else if(tmpStrValue == "pickupable")
  851. slot = SLOTP_RIGHT | SLOTP_LEFT | SLOTP_AMMO;
  852. else
  853. std::clog << "[Warning - MoveEvent::configureMoveEvent] Unknown slot type \"" << strValue << "\"" << std::endl;
  854. }
  855.  
  856. wieldInfo = 0;
  857. if(readXMLInteger(p, "lvl", intValue) || readXMLInteger(p, "level", intValue))
  858. {
  859. reqLevel = intValue;
  860. if(reqLevel > 0)
  861. wieldInfo |= WIELDINFO_LEVEL;
  862. }
  863.  
  864. if(readXMLInteger(p, "maglv", intValue) || readXMLInteger(p, "maglevel", intValue))
  865. {
  866. reqMagLevel = intValue;
  867. if(reqMagLevel > 0)
  868. wieldInfo |= WIELDINFO_MAGLV;
  869. }
  870.  
  871. if(readXMLString(p, "prem", strValue) || readXMLString(p, "premium", strValue))
  872. {
  873. premium = booleanString(strValue);
  874. if(premium)
  875. wieldInfo |= WIELDINFO_PREMIUM;
  876. }
  877.  
  878. StringVec vocStringVec;
  879. std::string error = "";
  880. xmlNodePtr vocationNode = p->children;
  881. while(vocationNode)
  882. {
  883. if(!parseVocationNode(vocationNode, vocEquipMap, vocStringVec, error))
  884. std::clog << "[Warning - MoveEvent::configureEvent] " << error << std::endl;
  885.  
  886. vocationNode = vocationNode->next;
  887. }
  888.  
  889. if(!vocEquipMap.empty())
  890. wieldInfo |= WIELDINFO_VOCREQ;
  891.  
  892. vocationString = parseVocationString(vocStringVec);
  893. }
  894. }
  895. else
  896. {
  897. std::clog << "[Error - MoveEvent::configureMoveEvent] No event found." << std::endl;
  898. return false;
  899. }
  900.  
  901. return true;
  902. }
  903.  
  904. bool MoveEvent::loadFunction(const std::string& functionName)
  905. {
  906. std::string tmpFunctionName = asLowerCaseString(functionName);
  907. if(tmpFunctionName == "onstepinfield")
  908. stepFunction = StepInField;
  909. else if(tmpFunctionName == "onaddfield")
  910. moveFunction = AddItemField;
  911. else if(tmpFunctionName == "onequipitem")
  912. equipFunction = EquipItem;
  913. else if(tmpFunctionName == "ondeequipitem")
  914. equipFunction = DeEquipItem;
  915. else
  916. {
  917. std::clog << "[Warning - MoveEvent::loadFunction] Function \"" << functionName << "\" does not exist." << std::endl;
  918. return false;
  919. }
  920.  
  921. m_scripted = EVENT_SCRIPT_FALSE;
  922. return true;
  923. }
  924.  
  925. MoveEvent_t MoveEvent::getEventType() const
  926. {
  927. if(m_eventType == MOVE_EVENT_NONE)
  928. std::clog << "[Error - MoveEvent::getEventType] MOVE_EVENT_NONE" << std::endl;
  929.  
  930. return m_eventType;
  931. }
  932.  
  933. void MoveEvent::setEventType(MoveEvent_t type)
  934. {
  935. m_eventType = type;
  936. }
  937.  
  938. uint32_t MoveEvent::StepInField(Creature* creature, Item* item)
  939. {
  940. if(MagicField* field = item->getMagicField())
  941. {
  942. field->onStepInField(creature, creature->getPlayer());
  943. return 1;
  944. }
  945.  
  946. return LUA_ERROR_ITEM_NOT_FOUND;
  947. }
  948.  
  949. uint32_t MoveEvent::AddItemField(Item* item)
  950. {
  951. if(MagicField* field = item->getMagicField())
  952. {
  953. if(Tile* tile = item->getTile())
  954. {
  955. if(CreatureVector* creatures = tile->getCreatures())
  956. {
  957. for(CreatureVector::iterator cit = creatures->begin(); cit != creatures->end(); ++cit)
  958. field->onStepInField(*cit);
  959. }
  960. }
  961.  
  962. return 1;
  963. }
  964.  
  965. return LUA_ERROR_ITEM_NOT_FOUND;
  966. }
  967.  
  968. bool MoveEvent::EquipItem(MoveEvent* moveEvent, Player* player, Item* item, slots_t slot, bool isCheck)
  969. {
  970. if(player->isItemAbilityEnabled(slot))
  971. return true;
  972.  
  973. if(!player->hasFlag(PlayerFlag_IgnoreEquipCheck) && moveEvent->getWieldInfo() != 0)
  974. {
  975. if(player->getLevel() < (uint32_t)moveEvent->getReqLevel() || player->getMagicLevel() < (uint32_t)moveEvent->getReqMagLv())
  976. return false;
  977.  
  978. if(moveEvent->isPremium() && !player->isPremium())
  979. return false;
  980.  
  981. if(!moveEvent->getVocEquipMap().empty() && moveEvent->getVocEquipMap().find(player->getVocationId()) == moveEvent->getVocEquipMap().end())
  982. return false;
  983. }
  984.  
  985. if(isCheck)
  986. return true;
  987.  
  988. const ItemType& it = Item::items[item->getID()];
  989. if(it.transformEquipTo)
  990. {
  991. Item* newItem = g_game.transformItem(item, it.transformEquipTo);
  992. g_game.startDecay(newItem);
  993. }
  994.  
  995. player->setItemAbility(slot, true);
  996. if(it.abilities.invisible)
  997. {
  998. Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_INVISIBLE, -1, 0);
  999. player->addCondition(condition);
  1000. }
  1001.  
  1002. if(it.abilities.manaShield)
  1003. {
  1004. Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_MANASHIELD, -1, 0);
  1005. player->addCondition(condition);
  1006. }
  1007.  
  1008. if(it.abilities.speed)
  1009. g_game.changeSpeed(player, it.abilities.speed);
  1010.  
  1011. if(it.abilities.conditionSuppressions)
  1012. {
  1013. player->setConditionSuppressions(it.abilities.conditionSuppressions, false);
  1014. player->sendIcons();
  1015. }
  1016.  
  1017. if(it.abilities.regeneration)
  1018. {
  1019. Condition* condition = Condition::createCondition((ConditionId_t)slot, CONDITION_REGENERATION, -1, 0);
  1020. if(it.abilities.healthGain)
  1021. condition->setParam(CONDITIONPARAM_HEALTHGAIN, it.abilities.healthGain);
  1022.  
  1023. if(it.abilities.healthTicks)
  1024. condition->setParam(CONDITIONPARAM_HEALTHTICKS, it.abilities.healthTicks);
  1025.  
  1026. if(it.abilities.manaGain)
  1027. condition->setParam(CONDITIONPARAM_MANAGAIN, it.abilities.manaGain);
  1028.  
  1029. if(it.abilities.manaTicks)
  1030. condition->setParam(CONDITIONPARAM_MANATICKS, it.abilities.manaTicks);
  1031.  
  1032. player->addCondition(condition);
  1033. }
  1034.  
  1035. bool needUpdateSkills = false;
  1036. for(uint32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i)
  1037. {
  1038. if(it.abilities.skills[i])
  1039. {
  1040. player->setVarSkill((skills_t)i, it.abilities.skills[i]);
  1041. if(!needUpdateSkills)
  1042. needUpdateSkills = true;
  1043. }
  1044.  
  1045. if(it.abilities.skillsPercent[i])
  1046. {
  1047. player->setVarSkill((skills_t)i, (int32_t)(player->getSkill((skills_t)i, SKILL_LEVEL) * ((it.abilities.skillsPercent[i] - 100) / 100.f)));
  1048. if(!needUpdateSkills)
  1049. needUpdateSkills = true;
  1050. }
  1051. }
  1052.  
  1053. if(needUpdateSkills)
  1054. player->sendSkills();
  1055.  
  1056. bool needUpdateStats = false;
  1057. for(uint32_t s = STAT_FIRST; s <= STAT_LAST; ++s)
  1058. {
  1059. if(it.abilities.stats[s])
  1060. {
  1061. player->setVarStats((stats_t)s, it.abilities.stats[s]);
  1062. if(!needUpdateStats)
  1063. needUpdateStats = true;
  1064. }
  1065.  
  1066. if(it.abilities.statsPercent[s])
  1067. {
  1068. player->setVarStats((stats_t)s, (int32_t)(player->getDefaultStats((stats_t)s) * ((it.abilities.statsPercent[s] - 100) / 100.f)));
  1069. if(!needUpdateStats)
  1070. needUpdateStats = true;
  1071. }
  1072. }
  1073.  
  1074. if(needUpdateStats)
  1075. player->sendStats();
  1076.  
  1077. return true;
  1078. }
  1079.  
  1080. bool MoveEvent::DeEquipItem(MoveEvent*, Player* player, Item* item, slots_t slot, bool isRemoval)
  1081. {
  1082. if(!player->isItemAbilityEnabled(slot))
  1083. return true;
  1084.  
  1085. const ItemType& it = Item::items[item->getID()];
  1086. if(isRemoval && it.transformDeEquipTo)
  1087. {
  1088. g_game.transformItem(item, it.transformDeEquipTo);
  1089. g_game.startDecay(item);
  1090. }
  1091.  
  1092. player->setItemAbility(slot, false);
  1093. if(it.abilities.invisible)
  1094. player->removeCondition(CONDITION_INVISIBLE, (ConditionId_t)slot);
  1095.  
  1096. if(it.abilities.manaShield)
  1097. player->removeCondition(CONDITION_MANASHIELD, (ConditionId_t)slot);
  1098.  
  1099. if(it.abilities.speed)
  1100. g_game.changeSpeed(player, -it.abilities.speed);
  1101.  
  1102. if(it.abilities.conditionSuppressions)
  1103. {
  1104. player->setConditionSuppressions(it.abilities.conditionSuppressions, true);
  1105. player->sendIcons();
  1106. }
  1107.  
  1108. if(it.abilities.regeneration)
  1109. player->removeCondition(CONDITION_REGENERATION, (ConditionId_t)slot);
  1110.  
  1111. bool needUpdateSkills = false;
  1112. for(uint32_t i = SKILL_FIRST; i <= SKILL_LAST; ++i)
  1113. {
  1114. if(it.abilities.skills[i])
  1115. {
  1116. needUpdateSkills = true;
  1117. player->setVarSkill((skills_t)i, -it.abilities.skills[i]);
  1118. }
  1119.  
  1120. if(it.abilities.skillsPercent[i])
  1121. {
  1122. needUpdateSkills = true;
  1123. player->setVarSkill((skills_t)i, -(int32_t)(player->getSkill((skills_t)i, SKILL_LEVEL) * ((it.abilities.skillsPercent[i] - 100) / 100.f)));
  1124. }
  1125. }
  1126.  
  1127. if(needUpdateSkills)
  1128. player->sendSkills();
  1129.  
  1130. bool needUpdateStats = false;
  1131. for(uint32_t s = STAT_FIRST; s <= STAT_LAST; ++s)
  1132. {
  1133. if(it.abilities.stats[s])
  1134. {
  1135. needUpdateStats = true;
  1136. player->setVarStats((stats_t)s, -it.abilities.stats[s]);
  1137. }
  1138.  
  1139. if(it.abilities.statsPercent[s])
  1140. {
  1141. needUpdateStats = true;
  1142. player->setVarStats((stats_t)s, -(int32_t)(player->getDefaultStats((stats_t)s) * ((it.abilities.statsPercent[s] - 100) / 100.f)));
  1143. }
  1144. }
  1145.  
  1146. if(needUpdateStats)
  1147. player->sendStats();
  1148.  
  1149. return true;
  1150. }
  1151.  
  1152. uint32_t MoveEvent::fireStepEvent(Creature* actor, Creature* creature, Item* item, const Position& pos, const Position& fromPos, const Position& toPos)
  1153. {
  1154. if(isScripted())
  1155. return executeStep(actor, creature, item, pos, fromPos, toPos);
  1156.  
  1157. return stepFunction(creature, item);
  1158. }
  1159.  
  1160. uint32_t MoveEvent::executeStep(Creature* actor, Creature* creature, Item* item, const Position& pos, const Position& fromPos, const Position& toPos)
  1161. {
  1162. //onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)
  1163. //onStepOut(cid, item, position, lastPosition, fromPosition, toPosition, actor)
  1164. if(m_interface->reserveEnv())
  1165. {
  1166. MoveEventScript::event = this;
  1167. ScriptEnviroment* env = m_interface->getEnv();
  1168. if(m_scripted == EVENT_SCRIPT_BUFFER)
  1169. {
  1170. env->setRealPos(creature->getPosition());
  1171. std::stringstream scriptstream;
  1172. scriptstream << "local cid = " << env->addThing(creature) << std::endl;
  1173.  
  1174. env->streamThing(scriptstream, "item", item, env->addThing(item));
  1175. env->streamPosition(scriptstream, "position", pos, 0);
  1176. env->streamPosition(scriptstream, "lastPosition", creature->getLastPosition(), 0);
  1177. env->streamPosition(scriptstream, "fromPosition", fromPos, 0);
  1178. env->streamPosition(scriptstream, "toPosition", toPos, 0);
  1179. scriptstream << "local actor = " << env->addThing(actor) << std::endl;
  1180.  
  1181. scriptstream << m_scriptData;
  1182. bool result = true;
  1183. if(m_interface->loadBuffer(scriptstream.str()))
  1184. {
  1185. lua_State* L = m_interface->getState();
  1186. result = m_interface->getGlobalBool(L, "_result", true);
  1187. }
  1188.  
  1189. m_interface->releaseEnv();
  1190. return result;
  1191. }
  1192. else
  1193. {
  1194. #ifdef __DEBUG_LUASCRIPTS__
  1195. std::stringstream desc;
  1196. desc << creature->getName() << " itemid: " << item->getID() << " - " << pos;
  1197. env->setEvent(desc.str());
  1198. #endif
  1199.  
  1200. env->setScriptId(m_scriptId, m_interface);
  1201. env->setRealPos(creature->getPosition());
  1202.  
  1203. lua_State* L = m_interface->getState();
  1204. m_interface->pushFunction(m_scriptId);
  1205. lua_pushnumber(L, env->addThing(creature));
  1206.  
  1207. LuaInterface::pushThing(L, item, env->addThing(item));
  1208. LuaInterface::pushPosition(L, pos, 0);
  1209. LuaInterface::pushPosition(L, creature->getLastPosition(), 0);
  1210. LuaInterface::pushPosition(L, fromPos, 0);
  1211. LuaInterface::pushPosition(L, toPos, 0);
  1212.  
  1213. lua_pushnumber(L, env->addThing(actor));
  1214. bool result = m_interface->callFunction(7);
  1215.  
  1216. m_interface->releaseEnv();
  1217. return result;
  1218. }
  1219. }
  1220. else
  1221. {
  1222. std::clog << "[Error - MoveEvent::executeStep] Call stack overflow." << std::endl;
  1223. return 0;
  1224. }
  1225. }
  1226.  
  1227. bool MoveEvent::fireEquip(Player* player, Item* item, slots_t slot, bool boolean)
  1228. {
  1229. if(isScripted())
  1230. return executeEquip(player, item, slot, boolean);
  1231.  
  1232. return equipFunction(this, player, item, slot, boolean);
  1233. }
  1234.  
  1235. bool MoveEvent::executeEquip(Player* player, Item* item, slots_t slot, bool boolean)
  1236. {
  1237. //onEquip(cid, item, slot, boolean)
  1238. //onDeEquip(cid, item, slot, boolean)
  1239. if(m_interface->reserveEnv())
  1240. {
  1241. MoveEventScript::event = this;
  1242. ScriptEnviroment* env = m_interface->getEnv();
  1243. if(m_scripted == EVENT_SCRIPT_BUFFER)
  1244. {
  1245. env->setRealPos(player->getPosition());
  1246. std::stringstream scriptstream;
  1247.  
  1248. scriptstream << "local cid = " << env->addThing(player) << std::endl;
  1249. env->streamThing(scriptstream, "item", item, env->addThing(item));
  1250. scriptstream << "local slot = " << slot << std::endl;
  1251. scriptstream << "local boolean = " << (boolean ? "true" : "false") << std::endl;
  1252.  
  1253. scriptstream << m_scriptData;
  1254. bool result = true;
  1255. if(m_interface->loadBuffer(scriptstream.str()))
  1256. {
  1257. lua_State* L = m_interface->getState();
  1258. result = m_interface->getGlobalBool(L, "_result", true);
  1259. }
  1260.  
  1261. m_interface->releaseEnv();
  1262. return result;
  1263. }
  1264. else
  1265. {
  1266. #ifdef __DEBUG_LUASCRIPTS__
  1267. std::stringstream desc;
  1268. desc << player->getName() << " itemid: " << item->getID() << " slot: " << slot;
  1269. env->setEvent(desc.str());
  1270. #endif
  1271.  
  1272. env->setScriptId(m_scriptId, m_interface);
  1273. env->setRealPos(player->getPosition());
  1274.  
  1275. lua_State* L = m_interface->getState();
  1276. m_interface->pushFunction(m_scriptId);
  1277.  
  1278. lua_pushnumber(L, env->addThing(player));
  1279. LuaInterface::pushThing(L, item, env->addThing(item));
  1280. lua_pushnumber(L, slot);
  1281. lua_pushboolean(L, boolean);
  1282.  
  1283. bool result = m_interface->callFunction(4);
  1284. m_interface->releaseEnv();
  1285. return result;
  1286. }
  1287. }
  1288. else
  1289. {
  1290. std::clog << "[Error - MoveEvent::executeEquip] Call stack overflow." << std::endl;
  1291. return false;
  1292. }
  1293. }
  1294.  
  1295. uint32_t MoveEvent::fireAddRemItem(Creature* actor, Item* item, Item* tileItem, const Position& pos)
  1296. {
  1297. if(isScripted())
  1298. return executeAddRemItem(actor, item, tileItem, pos);
  1299.  
  1300. return moveFunction(item);
  1301. }
  1302.  
  1303. uint32_t MoveEvent::executeAddRemItem(Creature* actor, Item* item, Item* tileItem, const Position& pos)
  1304. {
  1305. //onAddItem(moveItem, tileItem, position, cid)
  1306. //onRemoveItem(moveItem, tileItem, position, cid)
  1307. if(m_interface->reserveEnv())
  1308. {
  1309. MoveEventScript::event = this;
  1310. ScriptEnviroment* env = m_interface->getEnv();
  1311. if(m_scripted == EVENT_SCRIPT_BUFFER)
  1312. {
  1313. env->setRealPos(pos);
  1314. std::stringstream scriptstream;
  1315.  
  1316. env->streamThing(scriptstream, "moveItem", item, env->addThing(item));
  1317. env->streamThing(scriptstream, "tileItem", tileItem, env->addThing(tileItem));
  1318.  
  1319. env->streamPosition(scriptstream, "position", pos, 0);
  1320. scriptstream << "local cid = " << env->addThing(actor) << std::endl;
  1321.  
  1322. scriptstream << m_scriptData;
  1323. bool result = true;
  1324. if(m_interface->loadBuffer(scriptstream.str()))
  1325. {
  1326. lua_State* L = m_interface->getState();
  1327. result = m_interface->getGlobalBool(L, "_result", true);
  1328. }
  1329.  
  1330. m_interface->releaseEnv();
  1331. return result;
  1332. }
  1333. else
  1334. {
  1335. #ifdef __DEBUG_LUASCRIPTS__
  1336. std::stringstream desc;
  1337. if(tileItem)
  1338. desc << "tileid: " << tileItem->getID();
  1339.  
  1340. desc << " itemid: " << item->getID() << " - " << pos;
  1341. env->setEvent(desc.str());
  1342. #endif
  1343.  
  1344. env->setScriptId(m_scriptId, m_interface);
  1345. env->setRealPos(pos);
  1346.  
  1347. lua_State* L = m_interface->getState();
  1348. m_interface->pushFunction(m_scriptId);
  1349.  
  1350. LuaInterface::pushThing(L, item, env->addThing(item));
  1351. LuaInterface::pushThing(L, tileItem, env->addThing(tileItem));
  1352. LuaInterface::pushPosition(L, pos, 0);
  1353.  
  1354. lua_pushnumber(L, env->addThing(actor));
  1355. bool result = m_interface->callFunction(4);
  1356.  
  1357. m_interface->releaseEnv();
  1358. return result;
  1359. }
  1360. }
  1361. else
  1362. {
  1363. std::clog << "[Error - MoveEvent::executeAddRemItem] Call stack overflow." << std::endl;
  1364. return 0;
  1365. }
  1366. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement