Advertisement
Guest User

Untitled

a guest
Jan 9th, 2015
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.84 KB | None | 0 0
  1. //////////////////////////////////////////////////////////////////////
  2. // OpenTibia - an opensource roleplaying game
  3. //////////////////////////////////////////////////////////////////////
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. // This program is free software; you can redistribute it and/or
  7. // modify it under the terms of the GNU General Public License
  8. // as published by the Free Software Foundation; either version 2
  9. // of the License, or (at your option) any later version.
  10. //
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software Foundation,
  18. // Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19. //////////////////////////////////////////////////////////////////////
  20. #include "otpch.h"
  21. #include "creatureevent.h"
  22. #include "tools.h"
  23. #include "player.h"
  24.  
  25. CreatureEvents::CreatureEvents() :
  26. m_scriptInterface("CreatureScript Interface")
  27. {
  28.     m_scriptInterface.initState();
  29.     m_logInEvent = NULL;
  30.     m_logOutEvent = NULL;
  31.     m_onAdvance = NULL;
  32. }
  33.  
  34. CreatureEvents::~CreatureEvents()
  35. {
  36.     delete m_logInEvent;
  37.     delete m_logOutEvent;
  38.     delete m_onAdvance;
  39.  
  40.     CreatureEventList::iterator it;
  41.     for(it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it){
  42.         delete it->second;
  43.     }
  44. }
  45.  
  46. void CreatureEvents::clear()
  47. {
  48.     //clear global events
  49.     if(m_logInEvent){
  50.     m_logInEvent->clearEvent();
  51.     delete m_logInEvent;
  52.     m_logInEvent = NULL;
  53.     }
  54.     if(m_logOutEvent){
  55.     m_logOutEvent->clearEvent();
  56.     delete m_logOutEvent;
  57.     m_logOutEvent = NULL;
  58.     }
  59.     if(m_onAdvance){
  60.         m_onAdvance->clearEvent();
  61.         delete m_onAdvance;
  62.         m_onAdvance = NULL;
  63.     }
  64.     //clear creature events
  65.     CreatureEventList::iterator it;
  66.     for(it = m_creatureEvents.begin(); it != m_creatureEvents.end(); ++it){
  67.         it->second->clearEvent();
  68.     }
  69.     //clear lua state
  70.     m_scriptInterface.reInitState();
  71. }
  72.  
  73. LuaScriptInterface& CreatureEvents::getScriptInterface()
  74. {
  75.     return m_scriptInterface;
  76. }
  77.  
  78. std::string CreatureEvents::getScriptBaseName()
  79. {
  80.     return "creaturescripts";
  81. }
  82.  
  83. Event* CreatureEvents::getEvent(const std::string& nodeName)
  84. {
  85.     if(nodeName == "event"){
  86.         return new CreatureEvent(&m_scriptInterface);
  87.     }
  88.         return NULL;
  89.     }
  90.  
  91. bool CreatureEvents::registerEvent(Event* event, xmlNodePtr p)
  92. {
  93.     CreatureEvent* creatureEvent = dynamic_cast<CreatureEvent*>(event);
  94.     if(!creatureEvent){
  95.         return false;
  96.     }
  97.  
  98.     switch(creatureEvent->getEventType()){
  99.     case CREATURE_EVENT_NONE:
  100.         std::cout << "Error: [CreatureEvents::registerEvent] Trying to register event without type!." << std::endl;
  101.         return false;
  102.         break;
  103.     // global events are stored in
  104.     // member variables and their name is ignored!
  105.     case CREATURE_EVENT_LOGIN:
  106.         delete m_logInEvent;
  107.         m_logInEvent = creatureEvent;
  108.         return true;
  109.     case CREATURE_EVENT_LOGOUT:
  110.         delete m_logOutEvent;
  111.         m_logOutEvent = creatureEvent;
  112.         return true;
  113.     case CREATURE_EVENT_ADVANCE:
  114.         delete m_onAdvance;
  115.         m_onAdvance = creatureEvent;
  116.         return true;
  117.     // other events are stored in a std::map
  118.     default:
  119.         {
  120.             CreatureEvent* oldEvent = getEventByName(creatureEvent->getName(), false);
  121.             if(oldEvent){
  122.                 // if there was an event with the same that is not loaded
  123.                 // (happens when realoading), it is reused
  124.                 if(oldEvent->isLoaded() == false &&
  125.                     oldEvent->getEventType() == creatureEvent->getEventType()){
  126.                     oldEvent->copyEvent(creatureEvent);
  127.                 }
  128.                 return false;
  129.             }
  130.             else{
  131.                 //if not, register it normally
  132.                 m_creatureEvents[creatureEvent->getName()] = creatureEvent;
  133.                 return true;
  134.             }
  135.         }
  136.     }
  137. }
  138.  
  139. CreatureEvent* CreatureEvents::getEventByName(const std::string& name, bool forceLoaded /*= true*/)
  140. {
  141.     CreatureEventList::iterator it = m_creatureEvents.find(name);
  142.     if(it != m_creatureEvents.end()){
  143.         // After reloading, a creature can have script that was not
  144.         // loaded again, if is the case, return NULL
  145.         if(!forceLoaded || it->second->isLoaded()){
  146.             return it->second;
  147.         }
  148.     }
  149.         return NULL;
  150.     }
  151.  
  152. uint32_t CreatureEvents::playerLogIn(Player* player)
  153. {
  154.     // fire global event if is registered
  155.     if(m_logInEvent){
  156.         return m_logInEvent->executeOnLogin(player);
  157.     }
  158.         return 0;
  159.     }
  160.  
  161. uint32_t CreatureEvents::playerLogOut(Player* player)
  162. {
  163.     // fire global event if is registered
  164.     if(m_logOutEvent){
  165.         return m_logOutEvent->executeOnLogout(player);
  166.     }
  167.         return 0;
  168.     }
  169.    
  170. uint32_t CreatureEvents::playerAdvance(Player* player, AdvanceType_t stat, uint32_t fromLv, uint32_t toLv)
  171. {
  172.     //
  173.     if(m_onAdvance) return m_onAdvance->executeOnAdvance(player, stat, fromLv, toLv);
  174.     return 0;
  175. }
  176.  
  177. /////////////////////////////////////
  178.  
  179. CreatureEvent::CreatureEvent(LuaScriptInterface* _interface) :
  180. Event(_interface)
  181. {
  182.     m_type = CREATURE_EVENT_NONE;
  183.     m_isLoaded = false;
  184. }
  185.  
  186. CreatureEvent::~CreatureEvent()
  187. {
  188.     //
  189. }
  190.  
  191. bool CreatureEvent::configureEvent(xmlNodePtr p)
  192. {
  193.     std::string str;
  194.     //Name that will be used in monster xml files and
  195.     // lua function to register events to reference this event
  196.     if(readXMLString(p, "name", str)){
  197.         m_eventName = str;
  198.     }
  199.     else{
  200.         std::cout << "Error: [CreatureEvent::configureEvent] No name for creature event." << std::endl;
  201.         return false;
  202.     }
  203.     if(readXMLString(p, "type", str)){
  204.         if(str == "login"){
  205.             m_type = CREATURE_EVENT_LOGIN;
  206.         }
  207.         else if(str == "logout"){
  208.             m_type = CREATURE_EVENT_LOGOUT;
  209.         }
  210.         else if(str == "die"){
  211.             m_type = CREATURE_EVENT_DIE;
  212.         }
  213.         else if(str == "kill"){
  214.             m_type = CREATURE_EVENT_KILL;
  215.         }
  216.         else if(str == "preparedeath"){
  217.             m_type = CREATURE_EVENT_PREPAREDEATH;
  218.         }
  219.         else if(str == "saga"){
  220.             m_type = CREATURE_EVENT_SAGA;
  221.         }
  222.         else if(str == "advance"){
  223.             m_type = CREATURE_EVENT_ADVANCE;
  224.         }
  225.         else{
  226.             std::cout << "Error: [CreatureEvent::configureEvent] No valid type for creature event." << str << std::endl;
  227.             return false;
  228.         }
  229.     }
  230.     else{
  231.         std::cout << "Error: [CreatureEvent::configureEvent] No type for creature event."  << std::endl;
  232.         return false;
  233.     }
  234.     m_isLoaded = true;
  235.     return true;
  236. }
  237.  
  238. std::string CreatureEvent::getScriptEventName()
  239. {
  240.     //Depending on the type script event name is different
  241.     switch(m_type){
  242.     case CREATURE_EVENT_LOGIN:
  243.         return "onLogin";
  244.         break;
  245.     case CREATURE_EVENT_LOGOUT:
  246.         return "onLogout";
  247.         break;
  248.     case CREATURE_EVENT_DIE:
  249.         return "onDie";
  250.         break;
  251.     case CREATURE_EVENT_KILL:
  252.         return "onKill";
  253.         break;
  254.     case CREATURE_EVENT_PREPAREDEATH:
  255.         return "onPrepareDeath";
  256.         break;
  257.     case CREATURE_EVENT_SAGA:
  258.         return "onSaga";
  259.         break;
  260.     case CREATURE_EVENT_ADVANCE:
  261.         return "onAdvance";
  262.         break;
  263.  
  264.     case CREATURE_EVENT_NONE:
  265.     default:
  266.         return "";
  267.         break;
  268.     }
  269. }
  270.  
  271. void CreatureEvent::copyEvent(CreatureEvent* creatureEvent)
  272. {
  273.     m_scriptId = creatureEvent->m_scriptId;
  274.     m_scriptInterface = creatureEvent->m_scriptInterface;
  275.     m_scripted = creatureEvent->m_scripted;
  276.     m_isLoaded = creatureEvent->m_isLoaded;
  277. }
  278.  
  279. void CreatureEvent::clearEvent()
  280. {
  281.     m_scriptId = 0;
  282.     m_scriptInterface = NULL;
  283.     m_scripted = false;
  284.     m_isLoaded = false;
  285. }
  286.  
  287. uint32_t CreatureEvent::executeOnLogin(Player* player)
  288. {
  289.     //onLogin(cid)
  290.     if(m_scriptInterface->reserveScriptEnv()){
  291.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  292.  
  293.         #ifdef __DEBUG_LUASCRIPTS__
  294.         std::stringstream desc;
  295.         desc << player->getName();
  296.         env->setEventDesc(desc.str());
  297.         #endif
  298.  
  299.         env->setScriptId(m_scriptId, m_scriptInterface);
  300.         env->setRealPos(player->getPosition());
  301.  
  302.         uint32_t cid = env->addThing(player);
  303.  
  304.         lua_State* L = m_scriptInterface->getLuaState();
  305.  
  306.         m_scriptInterface->pushFunction(m_scriptId);
  307.         lua_pushnumber(L, cid);
  308.  
  309.         int32_t result = m_scriptInterface->callFunction(1);
  310.         m_scriptInterface->releaseScriptEnv();
  311.  
  312.         return (result == LUA_TRUE);
  313.     }
  314.     else{
  315.         std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnLogin" << std::endl;
  316.         return 0;
  317.     }
  318. }
  319.  
  320. uint32_t CreatureEvent::executeOnLogout(Player* player)
  321. {
  322.     //onLogout(cid)
  323.     if(m_scriptInterface->reserveScriptEnv()){
  324.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  325.  
  326.         #ifdef __DEBUG_LUASCRIPTS__
  327.         std::stringstream desc;
  328.         desc << player->getName();
  329.         env->setEventDesc(desc.str());
  330.         #endif
  331.  
  332.         env->setScriptId(m_scriptId, m_scriptInterface);
  333.         env->setRealPos(player->getPosition());
  334.  
  335.         uint32_t cid = env->addThing(player);
  336.  
  337.         lua_State* L = m_scriptInterface->getLuaState();
  338.  
  339.         m_scriptInterface->pushFunction(m_scriptId);
  340.         lua_pushnumber(L, cid);
  341.  
  342.         int32_t result = m_scriptInterface->callFunction(1);
  343.         m_scriptInterface->releaseScriptEnv();
  344.  
  345.         return (result == LUA_TRUE);
  346.     }
  347.     else{
  348.         std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnLogout" << std::endl;
  349.         return 0;
  350.     }
  351. }
  352.  
  353. uint32_t CreatureEvent::executeOnDie(Creature* creature, Item* corpse)
  354. {
  355.     //onDie(cid, corpse)
  356.     if(m_scriptInterface->reserveScriptEnv()){
  357.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  358.  
  359.         #ifdef __DEBUG_LUASCRIPTS__
  360.         std::stringstream desc;
  361.         desc << creature->getName();
  362.         env->setEventDesc(desc.str());
  363.         #endif
  364.  
  365.         env->setScriptId(m_scriptId, m_scriptInterface);
  366.         env->setRealPos(creature->getPosition());
  367.  
  368.         uint32_t cid = env->addThing(creature);
  369.         uint32_t corpseid = env->addThing(corpse);
  370.  
  371.         lua_State* L = m_scriptInterface->getLuaState();
  372.  
  373.         m_scriptInterface->pushFunction(m_scriptId);
  374.         lua_pushnumber(L, cid);
  375.         lua_pushnumber(L, corpseid);
  376.  
  377.         int32_t result = m_scriptInterface->callFunction(2);
  378.         m_scriptInterface->releaseScriptEnv();
  379.  
  380.         return (result == LUA_TRUE);
  381.     }
  382.     else{
  383.         std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnDie" << std::endl;
  384.         return 0;
  385.     }
  386. }
  387.  
  388. uint32_t CreatureEvent::executeOnKill(Creature* creature, Creature* target)
  389. {
  390. //onKill(cid, target)
  391.     if(m_scriptInterface->reserveScriptEnv()){
  392.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  393.  
  394.         #ifdef __DEBUG_LUASCRIPTS__
  395.         std::stringstream desc;
  396.         desc << creature->getName();
  397.         env->setEventDesc(desc.str());
  398.         #endif
  399.  
  400.         env->setScriptId(m_scriptId, m_scriptInterface);
  401.         env->setRealPos(creature->getPosition());
  402.    
  403.         uint32_t cid = env->addThing(creature);
  404.         uint32_t targetId = env->addThing(target);
  405.  
  406.         lua_State* L = m_scriptInterface->getLuaState();
  407.  
  408.         m_scriptInterface->pushFunction(m_scriptId);
  409.         lua_pushnumber(L, cid);
  410.         lua_pushnumber(L, targetId);
  411.  
  412.         int32_t result = m_scriptInterface->callFunction(2);
  413.         m_scriptInterface->releaseScriptEnv();
  414.  
  415.         return (result == LUA_TRUE);
  416.         }
  417.         else{
  418.             std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnKill" << std::endl;
  419.             return 0;
  420.         }
  421. }
  422.  
  423. uint32_t CreatureEvent::executeOnPrepareDeath(Player* player, Creature* killer)
  424. {
  425.     //onPrepareDeath(cid, killer)
  426.     if(m_scriptInterface->reserveScriptEnv())
  427.     {
  428.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  429.  
  430.         #ifdef __DEBUG_LUASCRIPTS__
  431.         char desc[35];
  432.         sprintf(desc, "%s", player->getName().c_str());
  433.         env->setEventDesc(desc);
  434.         #endif
  435.  
  436.         env->setScriptId(m_scriptId, m_scriptInterface);
  437.         env->setRealPos(player->getPosition());
  438.  
  439.         uint32_t cid = env->addThing(player);
  440.         uint32_t killercid = env->addThing(killer);
  441.  
  442.         lua_State* L = m_scriptInterface->getLuaState();
  443.  
  444.         m_scriptInterface->pushFunction(m_scriptId);
  445.         lua_pushnumber(L, cid);
  446.         lua_pushnumber(L, killercid);
  447.  
  448.         int32_t result = m_scriptInterface->callFunction(2);
  449.         m_scriptInterface->releaseScriptEnv();
  450.  
  451.         return (result != LUA_FALSE);
  452.     }
  453.     else
  454.     {
  455.         std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnPrepareDeath" << std::endl;
  456.         return 0;
  457.     }
  458. }
  459. uint32_t CreatureEvent::executeOnAdvance(Player* player, AdvanceType_t stat, uint32_t fromLv, uint32_t toLv)
  460. {
  461.     //onAdvance(cid, stat, from, to)
  462.     if(m_scriptInterface->reserveScriptEnv()){
  463.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  464.  
  465.         env->setScriptId(m_scriptId, m_scriptInterface);
  466.         env->setRealPos(player->getPosition());
  467.  
  468.         uint32_t cid = env->addThing(player);
  469.  
  470.         lua_State* L = m_scriptInterface->getLuaState();
  471.  
  472.         m_scriptInterface->pushFunction(m_scriptId);
  473.         lua_pushnumber(L, cid);
  474.         lua_pushnumber(L, (uint32_t)stat);
  475.         lua_pushnumber(L, fromLv);
  476.         lua_pushnumber(L, toLv);
  477.  
  478.         int32_t result = m_scriptInterface->callFunction(4);
  479.         m_scriptInterface->releaseScriptEnv();
  480.  
  481.         return (result == LUA_TRUE);
  482.     }
  483.     else{
  484.         std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnLogout" << std::endl;
  485.         return 0;
  486.     }
  487. }
  488.  
  489. uint32_t CreatureEvent::executeOnSaga(Creature* creature, Creature* killer)
  490. {
  491.     //onSaga(cid, target) -- like DBKO
  492.     if(m_scriptInterface->reserveScriptEnv())
  493.     {
  494.         ScriptEnviroment* env = m_scriptInterface->getScriptEnv();
  495.  
  496.         #ifdef __DEBUG_LUASCRIPTS__
  497.         char desc[30];
  498.         sprintf(desc, "%s", creature->getName().c_str());
  499.         env->setEventDesc(desc);
  500.         #endif
  501.  
  502.         env->setScriptId(m_scriptId, m_scriptInterface);
  503.         env->setRealPos(creature->getPosition());
  504.  
  505.         uint32_t cid = env->addThing(creature);
  506.         //uint32_t corpseid = env->addThing(corpse);
  507.         uint32_t killercid = env->addThing(killer);
  508.  
  509.         lua_State* L = m_scriptInterface->getLuaState();
  510.  
  511.         m_scriptInterface->pushFunction(m_scriptId);
  512.         lua_pushnumber(L, cid);
  513.         //lua_pushnumber(L, corpseid);
  514.         lua_pushnumber(L, killercid);
  515.  
  516.         int32_t result = m_scriptInterface->callFunction(2);
  517.         m_scriptInterface->releaseScriptEnv();
  518.  
  519.         return (result == LUA_TRUE);
  520.     }
  521.     else
  522.     {
  523.         std::cout << "[Error] Call stack overflow. CreatureEvent::executeOnDeath" << std::endl;
  524.         return 0;
  525.     }
  526. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement