Advertisement
Daanyel

movement.cpp

Jun 9th, 2019
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 37.97 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, true);
  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, false);
  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, bool equip)
  1228. {
  1229.     if(isScripted())
  1230.         return executeEquip(player, item, slot, boolean, equip);
  1231.  
  1232.     return equipFunction(this, player, item, slot, boolean);
  1233. }
  1234.  
  1235. bool MoveEvent::executeEquip(Player* player, Item* item, slots_t slot, bool boolean, bool equip)
  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.             lua_pushboolean(L, equip ? EquipItem(this, player, item, slot, boolean) : DeEquipItem(this, player, item, slot, boolean));
  1283.  
  1284.             bool result = m_interface->callFunction(5);
  1285.             m_interface->releaseEnv();
  1286.             return result;
  1287.         }
  1288.     }
  1289.     else
  1290.     {
  1291.         std::clog << "[Error - MoveEvent::executeEquip] Call stack overflow." << std::endl;
  1292.         return false;
  1293.     }
  1294. }
  1295.  
  1296. uint32_t MoveEvent::fireAddRemItem(Creature* actor, Item* item, Item* tileItem, const Position& pos)
  1297. {
  1298.     if(isScripted())
  1299.         return executeAddRemItem(actor, item, tileItem, pos);
  1300.  
  1301.     return moveFunction(item);
  1302. }
  1303.  
  1304. uint32_t MoveEvent::executeAddRemItem(Creature* actor, Item* item, Item* tileItem, const Position& pos)
  1305. {
  1306.     //onAddItem(moveItem, tileItem, position, cid)
  1307.     //onRemoveItem(moveItem, tileItem, position, cid)
  1308.     if(m_interface->reserveEnv())
  1309.     {
  1310.         MoveEventScript::event = this;
  1311.         ScriptEnviroment* env = m_interface->getEnv();
  1312.         if(m_scripted == EVENT_SCRIPT_BUFFER)
  1313.         {
  1314.             env->setRealPos(pos);
  1315.             std::stringstream scriptstream;
  1316.  
  1317.             env->streamThing(scriptstream, "moveItem", item, env->addThing(item));
  1318.             env->streamThing(scriptstream, "tileItem", tileItem, env->addThing(tileItem));
  1319.  
  1320.             env->streamPosition(scriptstream, "position", pos, 0);
  1321.             scriptstream << "local cid = " << env->addThing(actor) << std::endl;
  1322.  
  1323.             scriptstream << m_scriptData;
  1324.             bool result = true;
  1325.             if(m_interface->loadBuffer(scriptstream.str()))
  1326.             {
  1327.                 lua_State* L = m_interface->getState();
  1328.                 result = m_interface->getGlobalBool(L, "_result", true);
  1329.             }
  1330.  
  1331.             m_interface->releaseEnv();
  1332.             return result;
  1333.         }
  1334.         else
  1335.         {
  1336.             #ifdef __DEBUG_LUASCRIPTS__
  1337.             std::stringstream desc;
  1338.             if(tileItem)
  1339.                 desc << "tileid: " << tileItem->getID();
  1340.  
  1341.             desc << " itemid: " << item->getID() << " - " << pos;
  1342.             env->setEvent(desc.str());
  1343.             #endif
  1344.  
  1345.             env->setScriptId(m_scriptId, m_interface);
  1346.             env->setRealPos(pos);
  1347.  
  1348.             lua_State* L = m_interface->getState();
  1349.             m_interface->pushFunction(m_scriptId);
  1350.  
  1351.             LuaInterface::pushThing(L, item, env->addThing(item));
  1352.             LuaInterface::pushThing(L, tileItem, env->addThing(tileItem));
  1353.             LuaInterface::pushPosition(L, pos, 0);
  1354.  
  1355.             lua_pushnumber(L, env->addThing(actor));
  1356.             bool result = m_interface->callFunction(4);
  1357.  
  1358.             m_interface->releaseEnv();
  1359.             return result;
  1360.         }
  1361.     }
  1362.     else
  1363.     {
  1364.         std::clog << "[Error - MoveEvent::executeAddRemItem] Call stack overflow." << std::endl;
  1365.         return 0;
  1366.     }
  1367. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement