Advertisement
Guest User

mangos two patch

a guest
Sep 13th, 2014
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 162.90 KB | None | 0 0
  1. diff --git a/contrib/extractor/libmpq/common.cpp b/contrib/extractor/libmpq/common.cpp
  2. index 711dfb0..42d8c65 100644
  3. --- a/contrib/extractor/libmpq/common.cpp
  4. +++ b/contrib/extractor/libmpq/common.cpp
  5. @@ -38,7 +38,7 @@ unsigned int libmpq_lseek(mpq_archive* mpq_a, unsigned int pos)
  6.  {
  7.  #ifdef WIN32
  8.      return (unsigned int)_lseeki64(mpq_a->fd, pos, SEEK_SET);
  9. -#elif defined(__APPLE__)
  10. +#elif defined(__APPLE__) | defined(__FreeBSD__)
  11.      return (unsigned int)lseek(mpq_a->fd, pos, SEEK_SET);
  12.  #else
  13.      return (unsigned int)lseek64(mpq_a->fd, pos, SEEK_SET);
  14. diff --git a/contrib/vmap_extractor/vmapextract/vmapexport.cpp b/contrib/vmap_extractor/vmapextract/vmapexport.cpp
  15. index 905daf7..2da289b 100644
  16. --- a/contrib/vmap_extractor/vmapextract/vmapexport.cpp
  17. +++ b/contrib/vmap_extractor/vmapextract/vmapexport.cpp
  18. @@ -476,7 +476,7 @@ int main(int argc, char** argv)
  19.      //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  20.      // Create the working directory
  21.      if (mkdir(szWorkDirWmo
  22. -#ifdef __linux__
  23. +#if defined(__linux__) || defined(__FreeBSD__)
  24.                , 0711
  25.  #endif
  26.               ))
  27. diff --git a/dep/ACE_wrappers/configure b/dep/ACE_wrappers/configure
  28. index f122865..16f09b4 100755
  29. --- a/dep/ACE_wrappers/configure
  30. +++ b/dep/ACE_wrappers/configure
  31. @@ -6331,7 +6331,6 @@ if test "${enable_lib_streams+set}" = set; then :
  32.  
  33.  fi
  34.  
  35. -
  36.  # Check whether --enable-lib-svcconf was given.
  37.  if test "${enable_lib_svcconf+set}" = set; then :
  38.    enableval=$enable_lib_svcconf;
  39. @@ -10446,7 +10445,7 @@ else
  40.    PRELINK=""
  41.  fi
  42.  
  43. -
  44. +ace_cv_new_throws_bad_alloc_exception=no
  45.   # Check whether --enable-repo was given.
  46.  if test "${enable_repo+set}" = set; then :
  47.    enableval=$enable_repo;
  48. diff --git a/dep/CMakeLists.txt b/dep/CMakeLists.txt
  49. index 15c5a81..396103f 100644
  50. --- a/dep/CMakeLists.txt
  51. +++ b/dep/CMakeLists.txt
  52. @@ -20,3 +20,4 @@ endif()
  53.  
  54.  add_subdirectory(recastnavigation)
  55.  add_subdirectory(src)
  56. +add_subdirectory(lualib)
  57. \ No newline at end of file
  58. diff --git a/dep/include/g3dlite/G3D/System.h b/dep/include/g3dlite/G3D/System.h
  59. index 3183064..0fb8704 100755
  60. --- a/dep/include/g3dlite/G3D/System.h
  61. +++ b/dep/include/g3dlite/G3D/System.h
  62. @@ -20,6 +20,10 @@
  63.  #include "G3D/BinaryFormat.h"
  64.  #include <string>
  65.  
  66. +#if defined(__FreeBSD__)
  67. +#   include <sys/_timeval.h>
  68. +#endif
  69. +
  70.  #ifdef G3D_OSX
  71.  #   include <CoreServices/CoreServices.h>
  72.  #endif
  73. diff --git a/dep/src/g3dlite/uint128.cpp b/dep/src/g3dlite/uint128.cpp
  74. index 1f596fc..2fd58a3 100644
  75. --- a/dep/src/g3dlite/uint128.cpp
  76. +++ b/dep/src/g3dlite/uint128.cpp
  77. @@ -17,8 +17,8 @@ static void addAndCarry(const uint64& _a, const uint64& _b, uint64& carry, uint6
  78.          
  79.      // Break each number into 4 32-bit chunks. Since we are using uints, right-shifting will fill with zeros.
  80.      // This eliminates the need to and with 0xFFFFFFFF.
  81. -    uint32 a [2] = {_a & 0xFFFFFFFF, _a >> 32};
  82. -    uint32 b [2] = {_b & 0xFFFFFFFF, _b >> 32};
  83. +    uint32 a [2] = {static_cast<uint32>(_a & 0xFFFFFFFF), static_cast<uint32>(_a >> 32)};
  84. +    uint32 b [2] = {static_cast<uint32>(_b & 0xFFFFFFFF), static_cast<uint32>(_b >> 32)};
  85.  
  86.      uint64 tmp = uint64(a[0]) + b[0];
  87.  
  88. @@ -35,8 +35,8 @@ void multiplyAndCarry(const uint64& _a, const uint64& _b, uint64& carry, uint64&
  89.  
  90.      // Break each number into 4 32-bit chunks. Since we are using uints, right-shifting will fill with zeros.
  91.      // This eliminates the need to and with 0xFFFFFFFF.
  92. -    uint32 a [2] = {_a & 0xFFFFFFFF, _a >> 32};
  93. -    uint32 b [2] = {_b & 0xFFFFFFFF, _b >> 32};
  94. +    uint32 a [2] = {static_cast<uint32>(_a & 0xFFFFFFFF), static_cast<uint32>(_a >> 32)};
  95. +    uint32 b [2] = {static_cast<uint32>(_b & 0xFFFFFFFF), static_cast<uint32>(_b >> 32)};
  96.  
  97.      uint64 prod [2][2];
  98.      for(int i = 0; i < 2; ++i) {
  99. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
  100. index 3a4300c..9ddb25f 100644
  101. --- a/src/CMakeLists.txt
  102. +++ b/src/CMakeLists.txt
  103. @@ -24,10 +24,7 @@ if(WIN32)
  104.    )
  105.  endif()
  106.  
  107. -if (BUILD_SCRIPTS)
  108. -    add_subdirectory(scripts)
  109. -endif()
  110. -
  111. +add_subdirectory(bindings)
  112.  add_subdirectory(framework)
  113.  add_subdirectory(shared)
  114.  add_subdirectory(realmd)
  115. diff --git a/src/framework/Utilities/UnorderedMapSet.h b/src/framework/Utilities/UnorderedMapSet.h
  116. index 92bb6f9..52f9607 100644
  117. --- a/src/framework/Utilities/UnorderedMapSet.h
  118. +++ b/src/framework/Utilities/UnorderedMapSet.h
  119. @@ -94,9 +94,9 @@ HASH_NAMESPACE_END
  120.  using std::hash_map;
  121.  using std::hash_set;
  122.  #elif COMPILER == COMPILER_CLANG
  123. -#  define UNORDERED_MAP std::tr1::unordered_map
  124. -#  define UNORDERED_SET std::tr1::unordered_set
  125. -#  define HASH_NAMESPACE_START namespace std { namespace tr1 {
  126. +#  define UNORDERED_MAP std::unordered_map
  127. +#  define UNORDERED_SET std::unordered_set
  128. +#  define HASH_NAMESPACE_START namespace std { namespace __1 {
  129.  #  define HASH_NAMESPACE_END } }
  130.  #elif COMPILER == COMPILER_GNU && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
  131.  #  define UNORDERED_MAP std::tr1::unordered_map
  132. diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp
  133. index 77943f0..d5b93bd 100644
  134. --- a/src/game/AuctionHouseHandler.cpp
  135. +++ b/src/game/AuctionHouseHandler.cpp
  136. @@ -29,6 +29,7 @@
  137.  #include "Mail.h"
  138.  #include "Util.h"
  139.  #include "Chat.h"
  140. +#include "LuaEngine.h"
  141.  
  142.  // please DO NOT use iterator++, because it is slower than ++iterator!!!
  143.  // post-incrementation is always slower than pre-incrementation !
  144. @@ -367,6 +368,9 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recv_data)
  145.          SendAuctionCommandResult(AH, AUCTION_STARTED, AUCTION_OK);
  146.  
  147.          GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
  148. +    
  149. +        // Used by Eluna
  150. +        sEluna->OnAdd(auctionHouse);
  151.      }
  152.  }
  153.  
  154. @@ -521,6 +525,10 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recv_data)
  155.      CharacterDatabase.CommitTransaction();
  156.      sAuctionMgr.RemoveAItem(auction->itemGuidLow);
  157.      auctionHouse->RemoveAuction(auction->Id);
  158. +    
  159. +    // Used by Eluna
  160. +    sEluna->OnRemove(auctionHouse);
  161. +    
  162.      delete auction;
  163.  }
  164.  
  165. diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp
  166. index 692367a..5adb46c 100644
  167. --- a/src/game/AuctionHouseMgr.cpp
  168. +++ b/src/game/AuctionHouseMgr.cpp
  169. @@ -33,6 +33,7 @@
  170.  #include "WorldPacket.h"
  171.  #include "WorldSession.h"
  172.  #include "Mail.h"
  173. +#include "LuaEngine.h"
  174.  
  175.  #include "Policies/Singleton.h"
  176.  
  177. @@ -48,6 +49,14 @@ AuctionHouseMgr::~AuctionHouseMgr()
  178.          delete itr->second;
  179.  }
  180.  
  181. +AuctionHouseObject::~AuctionHouseObject()
  182. +{
  183. +    Eluna::RemoveRef(this);
  184. +    
  185. +    for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
  186. +        delete itr->second;
  187. +}
  188. +
  189.  AuctionHouseObject* AuctionHouseMgr::GetAuctionsMap(AuctionHouseEntry const* house)
  190.  {
  191.      if (sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
  192. diff --git a/src/game/AuctionHouseMgr.h b/src/game/AuctionHouseMgr.h
  193. index 703e25d..6852e08 100644
  194. --- a/src/game/AuctionHouseMgr.h
  195. +++ b/src/game/AuctionHouseMgr.h
  196. @@ -92,11 +92,7 @@ class AuctionHouseObject
  197.  {
  198.      public:
  199.          AuctionHouseObject() {}
  200. -        ~AuctionHouseObject()
  201. -        {
  202. -            for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
  203. -                delete itr->second;
  204. -        }
  205. +        ~AuctionHouseObject();
  206.  
  207.          typedef std::map<uint32, AuctionEntry*> AuctionEntryMap;
  208.          typedef std::pair<AuctionEntryMap::const_iterator, AuctionEntryMap::const_iterator> AuctionEntryMapBounds;
  209. diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
  210. index bdeb230..ce2b85e 100644
  211. --- a/src/game/CMakeLists.txt
  212. +++ b/src/game/CMakeLists.txt
  213. @@ -16,7 +16,13 @@
  214.  
  215.  set(LIBRARY_NAME game)
  216.  
  217. +file(GLOB SRC_FILES_LUAENGINE LuaEngine/*.cpp LuaEngine/*.h)
  218. +set(SRC_GRP_LUAENGINE
  219. +    ${SRC_FILES_LUAENGINE}
  220. +)
  221. +
  222.  set(LIBRARY_SRCS
  223. +    ${SRC_GRP_LUAENGINE}
  224.      AccountMgr.cpp
  225.      AccountMgr.h
  226.      AchievementMgr.cpp
  227. @@ -366,10 +372,12 @@ include_directories(
  228.    ${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouseBot
  229.    ${CMAKE_CURRENT_SOURCE_DIR}/BattleGround
  230.    ${CMAKE_CURRENT_SOURCE_DIR}/OutdoorPvP
  231. +  ${CMAKE_CURRENT_SOURCE_DIR}/LuaEngine
  232.    ${CMAKE_SOURCE_DIR}/dep/include/g3dlite
  233.    ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
  234.    ${CMAKE_SOURCE_DIR}/dep/recastnavigation/
  235.    ${CMAKE_SOURCE_DIR}/dep/include
  236. +  ${CMAKE_SOURCE_DIR}/dep/lualib
  237.    ${CMAKE_SOURCE_DIR}/src/shared
  238.    ${CMAKE_SOURCE_DIR}/src/framework
  239.    ${CMAKE_BINARY_DIR}
  240. @@ -378,6 +386,11 @@ include_directories(
  241.    ${ACE_INCLUDE_DIR}
  242.  )
  243.  
  244. +source_group("LuaEngine"
  245. +  FILES
  246. +    ${SRC_GRP_LUAENGINE}
  247. +)
  248. +
  249.  source_group("Object"
  250.    REGULAR_EXPRESSION .*
  251.  )
  252. @@ -429,6 +442,7 @@ add_library(${LIBRARY_NAME} STATIC
  253.  target_link_libraries(${LIBRARY_NAME}
  254.    shared
  255.    detour
  256. +  lualib
  257.  )
  258.  
  259.  if(UNIX)
  260. @@ -441,6 +455,7 @@ if(UNIX)
  261.  endif()
  262.  
  263.  add_dependencies(${LIBRARY_NAME} revision.h)
  264. +add_dependencies(${LIBRARY_NAME} lualib)
  265.  if(NOT ACE_USE_EXTERNAL)
  266.    add_dependencies(${LIBRARY_NAME} ACE_Project)
  267.  endif()
  268. @@ -459,3 +474,5 @@ if(PCH)
  269.      endif()
  270.    endif()
  271.  endif()
  272. +
  273. +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/LuaEngine/extensions DESTINATION ${BIN_DIR}/lua_scripts/)
  274. \ No newline at end of file
  275. diff --git a/src/game/Calendar.cpp b/src/game/Calendar.cpp
  276. index 979ede4..9a4ce28 100644
  277. --- a/src/game/Calendar.cpp
  278. +++ b/src/game/Calendar.cpp
  279. @@ -286,7 +286,7 @@ CalendarEvent* CalendarMgr::AddEvent(ObjectGuid const& guid, std::string title,
  280.  
  281.      uint64 nId = GetNewEventId();
  282.  
  283. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "CalendarMgr::AddEvent> ID("UI64FMTD"), '%s', Desc > '%s', type=%u, repeat=%u, maxInvites=%u, dungeonId=%d, flags=%u",
  284. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "CalendarMgr::AddEvent> ID(" UI64FMTD "), '%s', Desc > '%s', type=%u, repeat=%u, maxInvites=%u, dungeonId=%d, flags=%u",
  285.                       nId, title.c_str(), description.c_str(), type, repeatable, maxInvites, dungeonId, flags);
  286.  
  287.      CalendarEvent& newEvent = m_EventStore[nId];
  288. @@ -304,7 +304,7 @@ CalendarEvent* CalendarMgr::AddEvent(ObjectGuid const& guid, std::string title,
  289.  
  290.      CharacterDatabase.escape_string(title);
  291.      CharacterDatabase.escape_string(description);
  292. -    CharacterDatabase.PExecute("INSERT INTO calendar_events VALUES ("UI64FMTD", %u, %u, %u, %u, %d, %u, '%s', '%s')",
  293. +    CharacterDatabase.PExecute("INSERT INTO calendar_events VALUES (" UI64FMTD ", %u, %u, %u, %u, %d, %u, '%s', '%s')",
  294.                                 nId,
  295.                                 guid.GetCounter(),
  296.                                 guildId,
  297. @@ -388,7 +388,7 @@ CalendarInvite* CalendarMgr::AddInvite(CalendarEvent* event, ObjectGuid const& s
  298.          return NULL;
  299.      }
  300.  
  301. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Add Invite> eventId["UI64FMTD"], senderGuid[%s], inviteGuid[%s], Status[%u], rank[%u], text[%s], time[%u]",
  302. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Add Invite> eventId[" UI64FMTD "], senderGuid[%s], inviteGuid[%s], Status[%u], rank[%u], text[%s], time[%u]",
  303.                       event->EventId, senderGuid.GetString().c_str(), inviteeGuid.GetString().c_str(), uint32(status), uint32(rank), text.c_str(), uint32(statusTime));
  304.  
  305.      if (!event->AddInvite(invite))
  306. @@ -398,7 +398,7 @@ CalendarInvite* CalendarMgr::AddInvite(CalendarEvent* event, ObjectGuid const& s
  307.          return NULL;
  308.      }
  309.  
  310. -    CharacterDatabase.PExecute("INSERT INTO calendar_invites VALUES ("UI64FMTD", "UI64FMTD", %u, %u, %u, %u, %u)",
  311. +    CharacterDatabase.PExecute("INSERT INTO calendar_invites VALUES (" UI64FMTD ", " UI64FMTD ", %u, %u, %u, %u, %u)",
  312.                                 invite->InviteId,
  313.                                 event->EventId,
  314.                                 inviteeGuid.GetCounter(),
  315. @@ -661,7 +661,7 @@ void CalendarMgr::LoadCalendarsFromDB()
  316.              }
  317.              while (invitesQuery->NextRow());
  318.              sLog.outString();
  319. -            sLog.outString(">> Loaded "UI64FMTD" invites! %s", totalInvites, (deletedInvites != 0) ? "(deleted some invites without corresponding event!)" : "");
  320. +            sLog.outString(">> Loaded " UI64FMTD " invites! %s", totalInvites, (deletedInvites != 0) ? "(deleted some invites without corresponding event!)" : "");
  321.          }
  322.          else
  323.          {
  324. diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp
  325. index 7239ee2..58ae0f7 100644
  326. --- a/src/game/CalendarHandler.cpp
  327. +++ b/src/game/CalendarHandler.cpp
  328. @@ -58,7 +58,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recv_data*/)
  329.  
  330.          data << uint8(event->IsGuildEvent());
  331.          data << event->CreatorGuid.WriteAsPacked();
  332. -        DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "invite> EventId["UI64FMTD"], InviteId["UI64FMTD"], status[%u], rank[%u]",
  333. +        DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "invite> EventId[" UI64FMTD "], InviteId[" UI64FMTD "], status[%u], rank[%u]",
  334.                           event->EventId, (*itr)->InviteId, uint32((*itr)->Status), uint32((*itr)->Rank));
  335.      }
  336.  
  337. @@ -81,7 +81,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recv_data*/)
  338.          data << event->CreatorGuid.WriteAsPacked();
  339.  
  340.          std::string timeStr = TimeToTimestampStr(event->EventTime);
  341. -        DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Events> EventId["UI64FMTD"], Title[%s], Time[%s], Type[%u],  Flag[%u], DungeonId[%d], CreatorGuid[%s]",
  342. +        DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Events> EventId[" UI64FMTD "], Title[%s], Time[%s], Type[%u],  Flag[%u], DungeonId[%d], CreatorGuid[%s]",
  343.                           event->EventId, event->Title.c_str(), timeStr.c_str(), uint32(event->Type),
  344.                           uint32(event->Flags), event->DungeonId, event->CreatorGuid.GetString().c_str());
  345.      }
  346. @@ -221,7 +221,7 @@ void WorldSession::HandleCalendarEventSignup(WorldPacket& recv_data)
  347.  
  348.      recv_data >> eventId;
  349.      recv_data >> tentative; // uint8 == bool size in all compilator???
  350. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"] Tentative %u", eventId, uint32(tentative));
  351. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "] Tentative %u", eventId, uint32(tentative));
  352.  
  353.      if (CalendarEvent* event = sCalendarMgr.GetEventById(eventId))
  354.      {
  355. @@ -327,7 +327,7 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recv_data)
  356.      recv_data >> UnknownPackedTime;
  357.      recv_data >> flags;
  358.  
  359. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"], InviteId ["UI64FMTD"] Title %s, Description %s, type %u "
  360. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "], InviteId [" UI64FMTD "] Title %s, Description %s, type %u "
  361.                       "Repeatable %u, MaxInvites %u, Dungeon ID %d, Flags %u", eventId, inviteId, title.c_str(),
  362.                       description.c_str(), uint32(type), uint32(repetitionType), maxInvites, dungeonId, flags);
  363.  
  364. @@ -400,7 +400,7 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recv_data)
  365.  
  366.      recv_data >> eventId >> inviteId;
  367.      recv_data >> packedTime;
  368. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"] inviteId ["UI64FMTD"]",
  369. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "] inviteId [" UI64FMTD "]",
  370.                       eventId, inviteId);
  371.  
  372.      sCalendarMgr.CopyEvent(eventId, timeBitFieldsToSecs(packedTime), guid);
  373. @@ -524,7 +524,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recv_data)
  374.      uint32 status;
  375.  
  376.      recv_data >> eventId >> inviteId >> status;
  377. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD "], InviteId [" UI64FMTD "], status %u",
  378. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "], InviteId [" UI64FMTD "], status %u",
  379.                       eventId, inviteId, status);
  380.  
  381.      if (CalendarEvent* event = sCalendarMgr.GetEventById(eventId))
  382. @@ -557,7 +557,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recv_data)
  383.              invite->Status = CalendarInviteStatus(status);
  384.              invite->LastUpdateTime = time(NULL);
  385.  
  386. -            CharacterDatabase.PExecute("UPDATE calendar_invites SET status=%u, lastUpdateTime=%u WHERE inviteId = "UI64FMTD, status, uint32(invite->LastUpdateTime), invite->InviteId);
  387. +            CharacterDatabase.PExecute("UPDATE calendar_invites SET status=%u, lastUpdateTime=%u WHERE inviteId = " UI64FMTD , status, uint32(invite->LastUpdateTime), invite->InviteId);
  388.              sCalendarMgr.SendCalendarEventStatus(invite);
  389.              sCalendarMgr.SendCalendarClearPendingAction(_player);
  390.          }
  391. @@ -581,7 +581,7 @@ void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket& recv_data)
  392.      recv_data >> invitee.ReadAsPacked();
  393.      recv_data >> inviteId >> ownerInviteId >> eventId;
  394.  
  395. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"], ownerInviteId ["UI64FMTD"], Invitee ([%s] id: ["UI64FMTD"])",
  396. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "], ownerInviteId [" UI64FMTD "], Invitee ([%s] id: [" UI64FMTD "])",
  397.                       eventId, ownerInviteId, invitee.GetString().c_str(), inviteId);
  398.  
  399.      if (CalendarEvent* event = sCalendarMgr.GetEventById(eventId))
  400. @@ -604,7 +604,7 @@ void WorldSession::HandleCalendarEventStatus(WorldPacket& recv_data)
  401.  
  402.      recv_data >> invitee.ReadAsPacked();
  403.      recv_data >> eventId >> inviteId >> ownerInviteId >> status;
  404. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"] ownerInviteId ["UI64FMTD"], Invitee ([%s] id: ["UI64FMTD"], status %u",
  405. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "] ownerInviteId [" UI64FMTD "], Invitee ([%s] id: [" UI64FMTD "], status %u",
  406.                       eventId, ownerInviteId, invitee.GetString().c_str(), inviteId, status);
  407.  
  408.      if (CalendarEvent* event = sCalendarMgr.GetEventById(eventId))
  409. @@ -654,7 +654,7 @@ void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket& recv_data)
  410.  
  411.      recv_data >> invitee.ReadAsPacked();
  412.      recv_data >> eventId >>  inviteId >> ownerInviteId >> rank;
  413. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"] ownerInviteId ["UI64FMTD"], Invitee ([%s] id: ["UI64FMTD"], rank %u",
  414. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "] ownerInviteId [" UI64FMTD "], Invitee ([%s] id: [" UI64FMTD "], rank %u",
  415.                       eventId, ownerInviteId, invitee.GetString().c_str(), inviteId, rank);
  416.  
  417.      if (CalendarEvent* event = sCalendarMgr.GetEventById(eventId))
  418. @@ -706,7 +706,7 @@ void WorldSession::HandleCalendarComplain(WorldPacket& recv_data)
  419.  
  420.      recv_data >> badGuyGuid;
  421.      recv_data >> eventId >>  inviteId;
  422. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId ["UI64FMTD"], BadGuyGuid ([%s] inviteId: ["UI64FMTD"])",
  423. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "EventId [" UI64FMTD "], BadGuyGuid ([%s] inviteId: [" UI64FMTD "])",
  424.                       eventId, badGuyGuid.GetString().c_str(), inviteId);
  425.  
  426.      // Remove the invite
  427. @@ -759,7 +759,7 @@ void CalendarMgr::SendCalendarEventInviteAlert(CalendarInvite const* invite)
  428.      data << invite->SenderGuid.WriteAsPacked();
  429.      //data.hexlike();
  430.  
  431. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "SendCalendarInviteAlert> senderGuid[%s], inviteeGuid[%s], EventId["UI64FMTD"], Status[%u], InviteId["UI64FMTD"]",
  432. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "SendCalendarInviteAlert> senderGuid[%s], inviteeGuid[%s], EventId[" UI64FMTD "], Status[%u], InviteId[" UI64FMTD "]",
  433.                       invite->SenderGuid.GetString().c_str(), invite->InviteeGuid.GetString().c_str(), event->EventId, uint32(invite->Status), invite->InviteId);
  434.  
  435.      if (event->IsGuildEvent() || event->IsGuildAnnouncement())
  436. @@ -799,7 +799,7 @@ void CalendarMgr::SendCalendarEventInvite(CalendarInvite const* invite)
  437.          data << secsToTimeBitFields(statusTime);
  438.      data << uint8(invite->SenderGuid != invite->InviteeGuid); // false only if the invite is sign-up (invitee create himself his invite)
  439.  
  440. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "SendCalendarInvit> %s senderGuid[%s], inviteeGuid[%s], EventId["UI64FMTD"], Status[%u], InviteId["UI64FMTD"]",
  441. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "SendCalendarInvit> %s senderGuid[%s], inviteeGuid[%s], EventId[" UI64FMTD "], Status[%u], InviteId[" UI64FMTD "]",
  442.                       preInvite ? "is PreInvite," : "", invite->SenderGuid.GetString().c_str(), invite->InviteeGuid.GetString().c_str(), eventId, uint32(invite->Status), invite->InviteId);
  443.  
  444.      //data.hexlike();
  445. @@ -855,7 +855,7 @@ void CalendarMgr::SendCalendarEvent(Player* player, CalendarEvent const* event,
  446.          return;
  447.  
  448.      std::string timeStr = TimeToTimestampStr(event->EventTime);
  449. -    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "SendCalendarEvent> sendType[%u], CreatorGuid[%s], EventId["UI64FMTD"], Type[%u], Flags[%u], Title[%s]",
  450. +    DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "SendCalendarEvent> sendType[%u], CreatorGuid[%s], EventId[" UI64FMTD "], Type[%u], Flags[%u], Title[%s]",
  451.                       sendType, event->CreatorGuid.GetString().c_str(), event->EventId, uint32(event->Type), event->Flags, event->Title.c_str());
  452.  
  453.      WorldPacket data(SMSG_CALENDAR_SEND_EVENT);
  454. @@ -893,7 +893,7 @@ void CalendarMgr::SendCalendarEvent(Player* player, CalendarEvent const* event,
  455.          data << secsToTimeBitFields(invite->LastUpdateTime);
  456.          data << invite->Text;
  457.  
  458. -        DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Invite> InviteId["UI64FMTD"], InviteLvl[%u], Status[%u], Rank[%u],  GuildEvent[%s], Text[%s]",
  459. +        DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Invite> InviteId[" UI64FMTD "], InviteLvl[%u], Status[%u], Rank[%u],  GuildEvent[%s], Text[%s]",
  460.                           invite->InviteId, uint32(inviteeLevel), uint32(invite->Status), uint32(invite->Rank),
  461.                           (event->IsGuildEvent() && event->GuildId == inviteeGuildId) ? "true" : "false", invite->Text.c_str());
  462.      }
  463. diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
  464. index 6d6a63e..003161f 100644
  465. --- a/src/game/CharacterHandler.cpp
  466. +++ b/src/game/CharacterHandler.cpp
  467. @@ -40,6 +40,7 @@
  468.  #include "Language.h"
  469.  #include "SpellMgr.h"
  470.  #include "Calendar.h"
  471. +#include "LuaEngine.h"
  472.  
  473.  // config option SkipCinematics supported values
  474.  enum CinematicsSkipMode
  475. @@ -488,6 +489,9 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recv_data)
  476.      BASIC_LOG("Account: %d (IP: %s) Create Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), pNewChar->GetGUIDLow());
  477.      sLog.outChar("Account: %d (IP: %s) Create Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), pNewChar->GetGUIDLow());
  478.  
  479. +    // Used by Eluna
  480. +    sEluna->OnCreate(pNewChar);
  481. +    
  482.      delete pNewChar;                                        // created only to call SaveToDB()
  483.  }
  484.  
  485. @@ -540,6 +544,9 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recv_data)
  486.      BASIC_LOG("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), lowguid);
  487.      sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), lowguid);
  488.  
  489. +    // Used by Eluna
  490. +    sEluna->OnDelete(lowguid);
  491. +    
  492.      if (sLog.IsOutCharDump())                               // optimize GetPlayerDump call
  493.      {
  494.          std::string dump = PlayerDumpWriter().GetDump(lowguid);
  495. @@ -803,7 +810,12 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
  496.      }
  497.  
  498.      if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
  499. +    {
  500. +        // Eluna
  501. +        sEluna->OnFirstLogin(pCurrChar);
  502. +        
  503.          pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST);
  504. +    }
  505.  
  506.      // show time before shutdown if shutdown planned.
  507.      if (sWorld.IsShutdowning())
  508. @@ -831,6 +843,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
  509.          pCurrChar->SetStandState(UNIT_STAND_STATE_STAND);
  510.  
  511.      m_playerLoading = false;
  512. +    
  513. +    // Eluna
  514. +    sEluna->OnLogin(pCurrChar);
  515.  
  516.      // Handle Login-Achievements (should be handled after loading)
  517.      pCurrChar->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1);
  518. diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
  519. index fce786c..2fd32a7 100644
  520. --- a/src/game/Chat.cpp
  521. +++ b/src/game/Chat.cpp
  522. @@ -35,6 +35,7 @@
  523.  #include "PoolManager.h"
  524.  #include "GameEventMgr.h"
  525.  #include "AuctionHouseBot/AuctionHouseBot.h"
  526. +#include "LuaEngine.h"
  527.  
  528.  // Supported shift-links (client generated and server side)
  529.  // |color|Hachievement:achievement_id:player_guid_hex:completed_0_1:mm:dd:yy_from_2000:criteriaMask1:criteriaMask2:criteriaMask3:criteriaMask4|h[name]|h|r
  530. @@ -1259,6 +1260,9 @@ void ChatHandler::ExecuteCommand(const char* text)
  531.          }
  532.          case CHAT_COMMAND_UNKNOWN_SUBCOMMAND:
  533.          {
  534. +            if (!sEluna->OnCommand(m_session ? m_session->GetPlayer() : NULL, fullcmd.c_str()))
  535. +                return;
  536. +            
  537.              SendSysMessage(LANG_NO_SUBCMD);
  538.              ShowHelpForCommand(command->ChildCommands, text);
  539.              SetSentErrorMessage(true);
  540. @@ -1266,6 +1270,9 @@ void ChatHandler::ExecuteCommand(const char* text)
  541.          }
  542.          case CHAT_COMMAND_UNKNOWN:
  543.          {
  544. +            if (!sEluna->OnCommand(m_session ? m_session->GetPlayer() : NULL, fullcmd.c_str()))
  545. +                return;
  546. +            
  547.              SendSysMessage(LANG_NO_CMD);
  548.              SetSentErrorMessage(true);
  549.              break;
  550. diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
  551. index a6839df..1ed6fc8 100644
  552. --- a/src/game/ChatHandler.cpp
  553. +++ b/src/game/ChatHandler.cpp
  554. @@ -35,6 +35,7 @@
  555.  #include "Util.h"
  556.  #include "GridNotifiersImpl.h"
  557.  #include "CellImpl.h"
  558. +#include "LuaEngine.h"
  559.  
  560.  bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
  561.  {
  562. @@ -180,11 +181,26 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  563.                  break;
  564.  
  565.              if (type == CHAT_MSG_SAY)
  566. +            {
  567. +                if (!sEluna->OnChat(GetPlayer(), type, lang, msg))
  568. +                    return;
  569. +                
  570.                  GetPlayer()->Say(msg, lang);
  571. +            }
  572.              else if (type == CHAT_MSG_EMOTE)
  573. +            {
  574. +                if (!sEluna->OnChat(GetPlayer(), type, LANG_UNIVERSAL, msg))
  575. +                    return;
  576. +                
  577.                  GetPlayer()->TextEmote(msg);
  578. +            }
  579.              else if (type == CHAT_MSG_YELL)
  580. +            {
  581. +                if (!sEluna->OnChat(GetPlayer(), type, lang, msg))
  582. +                    return;
  583. +                
  584.                  GetPlayer()->Yell(msg, lang);
  585. +            }
  586.          } break;
  587.  
  588.          case CHAT_MSG_WHISPER:
  589. @@ -223,6 +239,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  590.                  }
  591.              }
  592.  
  593. +            // Used by Eluna
  594. +            sEluna->OnChat(GetPlayer(), type, lang, msg, player);
  595.              GetPlayer()->Whisper(msg, lang, player->GetObjectGuid());
  596.          } break;
  597.  
  598. @@ -255,6 +273,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  599.  
  600.              if ((type == CHAT_MSG_PARTY_LEADER) && !group->IsLeader(_player->GetObjectGuid()))
  601.                  return;
  602. +            
  603. +            // Used by Eluna
  604. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group))
  605. +                return;
  606.  
  607.              WorldPacket data;
  608.              ChatHandler::BuildChatPacket(data, ChatMsg(type), msg.c_str(), Language(lang), _player->GetChatTag(), _player->GetObjectGuid(), _player->GetName());
  609. @@ -281,8 +303,14 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  610.  
  611.              if (GetPlayer()->GetGuildId())
  612.                  if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId()))
  613. +                {
  614. +                    // Used by Eluna
  615. +                    if (!sEluna->OnChat(GetPlayer(), type, lang, msg, guild))
  616. +                        return;
  617. +                    
  618.                      guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
  619. -
  620. +                }
  621. +                
  622.              break;
  623.          }
  624.          case CHAT_MSG_OFFICER:
  625. @@ -304,8 +332,14 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  626.  
  627.              if (GetPlayer()->GetGuildId())
  628.                  if (Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId()))
  629. +                {
  630. +                    // Used by Eluna
  631. +                    if (!sEluna->OnChat(GetPlayer(), type, lang, msg, guild))
  632. +                        return;
  633. +                    
  634.                      guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
  635. -
  636. +                }
  637. +                
  638.              break;
  639.          }
  640.          case CHAT_MSG_RAID:
  641. @@ -334,6 +368,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  642.                      return;
  643.              }
  644.  
  645. +            // Used by Eluna
  646. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group))
  647. +                return;
  648. +            
  649.              WorldPacket data;
  650.              ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, msg.c_str(), Language(lang), _player->GetChatTag(), _player->GetObjectGuid(), _player->GetName());
  651.              group->BroadcastPacket(&data, false);
  652. @@ -364,6 +402,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  653.                      return;
  654.              }
  655.  
  656. +            // Used by Eluna
  657. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group))
  658. +                return;
  659. +            
  660.              WorldPacket data;
  661.              ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, msg.c_str(), Language(lang), _player->GetChatTag(), _player->GetObjectGuid(), _player->GetName());
  662.              group->BroadcastPacket(&data, false);
  663. @@ -385,6 +427,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  664.                      !(group->IsLeader(GetPlayer()->GetObjectGuid()) || group->IsAssistant(GetPlayer()->GetObjectGuid())))
  665.                  return;
  666.  
  667. +            // Used by Eluna
  668. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group))
  669. +                return;
  670. +            
  671.              WorldPacket data;
  672.              // in battleground, raid warning is sent only to players in battleground - code is ok
  673.              ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, msg.c_str(), Language(lang), _player->GetChatTag(), _player->GetObjectGuid(), _player->GetName());
  674. @@ -406,6 +452,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  675.              Group* group = GetPlayer()->GetGroup();
  676.              if (!group || !group->isBGGroup())
  677.                  return;
  678. +            
  679. +            // Used by Eluna
  680. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group))
  681. +                return;
  682.  
  683.              WorldPacket data;
  684.              ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, msg.c_str(), Language(lang), _player->GetChatTag(), _player->GetObjectGuid(), _player->GetName());
  685. @@ -427,6 +477,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  686.              Group* group = GetPlayer()->GetGroup();
  687.              if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetObjectGuid()))
  688.                  return;
  689. +            
  690. +            // Used by Eluna
  691. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group))
  692. +                return;
  693.  
  694.              WorldPacket data;
  695.              ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, msg.c_str(), Language(lang), _player->GetChatTag(), _player->GetObjectGuid(), _player->GetName());
  696. @@ -447,7 +501,13 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  697.  
  698.              if (ChannelMgr* cMgr = channelMgr(_player->GetTeam()))
  699.                  if (Channel* chn = cMgr->GetChannel(channel, _player))
  700. +                {
  701. +                    // Used by Eluna
  702. +                    if (!sEluna->OnChat(GetPlayer(), type, lang, msg, chn))
  703. +                        return;
  704. +                    
  705.                      chn->Say(_player, msg.c_str(), lang);
  706. +                }
  707.          } break;
  708.  
  709.          case CHAT_MSG_AFK:
  710. @@ -473,6 +533,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  711.  
  712.                      _player->ToggleAFK();
  713.                  }
  714. +                // Used by Eluna
  715. +                if (!sEluna->OnChat(GetPlayer(), type, lang, msg))
  716. +                    return;
  717.              }
  718.              break;
  719.          }
  720. @@ -497,6 +560,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recv_data)
  721.  
  722.                  _player->ToggleDND();
  723.              }
  724. +            // Used by Eluna
  725. +            if (!sEluna->OnChat(GetPlayer(), type, lang, msg))
  726. +                return;
  727. +            
  728.              break;
  729.          }
  730.  
  731. @@ -513,6 +580,9 @@ void WorldSession::HandleEmoteOpcode(WorldPacket& recv_data)
  732.  
  733.      uint32 emote;
  734.      recv_data >> emote;
  735. +    
  736. +    // Used by Eluna
  737. +    sEluna->OnEmote(GetPlayer(), emote);
  738.      GetPlayer()->HandleEmoteCommand(emote);
  739.  }
  740.  
  741. @@ -566,6 +636,9 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recv_data)
  742.      recv_data >> text_emote;
  743.      recv_data >> emoteNum;
  744.      recv_data >> guid;
  745. +    
  746. +    // Used by Eluna
  747. +    sEluna->OnTextEmote(GetPlayer(), text_emote, emoteNum, guid);
  748.  
  749.      EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
  750.      if (!em)
  751. diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp
  752. index 4708392..53c33f6 100644
  753. --- a/src/game/Corpse.cpp
  754. +++ b/src/game/Corpse.cpp
  755. @@ -26,6 +26,7 @@
  756.  #include "GossipDef.h"
  757.  #include "World.h"
  758.  #include "ObjectMgr.h"
  759. +#include "LuaEngine.h"
  760.  
  761.  Corpse::Corpse(CorpseType type) : WorldObject(),
  762.      loot(this),
  763. @@ -46,6 +47,7 @@ Corpse::Corpse(CorpseType type) : WorldObject(),
  764.  
  765.  Corpse::~Corpse()
  766.  {
  767. +    Eluna::RemoveRef(this);
  768.  }
  769.  
  770.  void Corpse::AddToWorld()
  771. diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
  772. index 142d904..a0e571d 100644
  773. --- a/src/game/Creature.cpp
  774. +++ b/src/game/Creature.cpp
  775. @@ -49,6 +49,7 @@
  776.  #include "CellImpl.h"
  777.  #include "movement/MoveSplineInit.h"
  778.  #include "CreatureLinkingMgr.h"
  779. +#include "LuaEngine.h"
  780.  
  781.  // apply implementation of the singletons
  782.  #include "Policies/Singleton.h"
  783. @@ -155,11 +156,15 @@ Creature::Creature(CreatureSubtype subtype) : Unit(),
  784.      m_CreatureSpellCooldowns.clear();
  785.      m_CreatureCategoryCooldowns.clear();
  786.  
  787. +    DisableReputationGain = false;
  788. +    
  789.      SetWalk(true, true);
  790.  }
  791.  
  792.  Creature::~Creature()
  793.  {
  794. +    Eluna::RemoveRef(this);
  795. +    
  796.      CleanupsBeforeDelete();
  797.  
  798.      m_vendorItemCounts.clear();
  799. @@ -170,6 +175,9 @@ Creature::~Creature()
  800.  
  801.  void Creature::AddToWorld()
  802.  {
  803. +    if (!IsInWorld())
  804. +        sEluna->OnAddToWorld(this);
  805. +    
  806.      ///- Register the creature for guid lookup
  807.      if (!IsInWorld() && GetObjectGuid().IsCreatureOrVehicle())
  808.          GetMap()->GetObjectsStore().insert<Creature>(GetObjectGuid(), (Creature*)this);
  809. @@ -179,6 +187,9 @@ void Creature::AddToWorld()
  810.  
  811.  void Creature::RemoveFromWorld()
  812.  {
  813. +    if (IsInWorld())
  814. +        sEluna->OnRemoveFromWorld(this);
  815. +    
  816.      ///- Remove the creature from the accessor
  817.      if (IsInWorld() && GetObjectGuid().IsCreatureOrVehicle())
  818.          GetMap()->GetObjectsStore().erase<Creature>(GetObjectGuid(), (Creature*)NULL);
  819. @@ -1056,6 +1067,18 @@ void Creature::SaveToDB()
  820.      SaveToDB(GetMapId(), data->spawnMask, GetPhaseMask());
  821.  }
  822.  
  823. +bool Creature::isTappedBy(Player const* player) const
  824. +{
  825. +    if (player == GetOriginalLootRecipient())
  826. +        return true;
  827. +    
  828. +    Group const* playerGroup = player->GetGroup();
  829. +    if (!playerGroup || playerGroup != GetGroupLootRecipient()) // if we dont have a group we arent the recipient
  830. +        return false;
  831. +    
  832. +    return true;
  833. +}
  834. +
  835.  void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
  836.  {
  837.      // update in loaded data
  838. @@ -2177,6 +2200,13 @@ bool Creature::HasCategoryCooldown(uint32 spell_id) const
  839.      return (itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL));
  840.  }
  841.  
  842. +uint32 Creature::GetCreatureSpellCooldownDelay(uint32 spellId) const
  843. +{
  844. +    CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spellId);
  845. +    time_t t = time(NULL);
  846. +    return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0);
  847. +}
  848. +
  849.  bool Creature::HasSpellCooldown(uint32 spell_id) const
  850.  {
  851.      CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id);
  852. diff --git a/src/game/Creature.h b/src/game/Creature.h
  853. index 4134e68..59708e1 100644
  854. --- a/src/game/Creature.h
  855. +++ b/src/game/Creature.h
  856. @@ -510,6 +510,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
  857.          bool IsCorpse() const { return getDeathState() ==  CORPSE; }
  858.          bool IsDespawned() const { return getDeathState() ==  DEAD; }
  859.          void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
  860. +        uint32 GetCorpseDelay() const { return m_corpseDelay; }
  861.          bool IsRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
  862.          bool IsCivilian() const { return GetCreatureInfo()->ExtraFlags & CREATURE_FLAG_EXTRA_CIVILIAN; }
  863.         bool IsGuard() const { return GetCreatureInfo()->ExtraFlags & CREATURE_FLAG_EXTRA_GUARD; }
  864. @@ -573,6 +574,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
  865.          void AddCreatureSpellCooldown(uint32 spellid);
  866.          bool HasSpellCooldown(uint32 spell_id) const;
  867.          bool HasCategoryCooldown(uint32 spell_id) const;
  868. +        uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const;
  869.  
  870.          bool HasSpell(uint32 spellID) const override;
  871.  
  872. @@ -634,6 +636,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
  873.          uint32 GetLootGroupRecipientId() const { return m_lootGroupRecipientId; }
  874.          Player* GetLootRecipient() const;                   // use group cases as prefered
  875.          Group* GetGroupLootRecipient() const;
  876. +        bool isTappedBy(Player const* player) const;
  877.          bool HasLootRecipient() const { return m_lootGroupRecipientId || m_lootRecipientGuid; }
  878.          bool IsGroupLootRecipient() const { return m_lootGroupRecipientId; }
  879.          void SetLootRecipient(Unit* unit);
  880. @@ -731,6 +734,9 @@ class MANGOS_DLL_SPEC Creature : public Unit
  881.  
  882.          void SetVirtualItem(VirtualItemSlot slot, uint32 item_id) { SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, item_id); }
  883.  
  884. +        void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
  885. +        bool IsReputationGainDisabled() { return DisableReputationGain; }
  886. +        
  887.      protected:
  888.          bool MeetsSelectAttackingRequirement(Unit* pTarget, SpellEntry const* pSpellInfo, uint32 selectFlags) const;
  889.  
  890. @@ -781,6 +787,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
  891.          float m_combatStartZ;
  892.  
  893.          Position m_respawnPos;
  894. +        
  895. +        bool DisableReputationGain;
  896.  
  897.      private:
  898.          GridReference<Creature> m_gridRef;
  899. diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
  900. index 0377274..064d47a 100644
  901. --- a/src/game/GameObject.cpp
  902. +++ b/src/game/GameObject.cpp
  903. @@ -40,7 +40,9 @@
  904.  #include "Util.h"
  905.  #include "ScriptMgr.h"
  906.  #include "vmap/GameObjectModel.h"
  907. +#include "CreatureAISelector.h"
  908.  #include "SQLStorages.h"
  909. +#include "LuaEngine.h"
  910.  #include <G3D/Quat.h>
  911.  
  912.  GameObject::GameObject() : WorldObject(),
  913. @@ -73,11 +75,16 @@ GameObject::GameObject() : WorldObject(),
  914.  
  915.  GameObject::~GameObject()
  916.  {
  917. +    Eluna::RemoveRef(this);
  918. +    
  919.      delete m_model;
  920.  }
  921.  
  922.  void GameObject::AddToWorld()
  923.  {
  924. +    if (!IsInWorld())
  925. +        sEluna->OnAddToWorld(this);
  926. +    
  927.      ///- Register the gameobject for guid lookup
  928.      if (!IsInWorld())
  929.          GetMap()->GetObjectsStore().insert<GameObject>(GetObjectGuid(), (GameObject*)this);
  930. @@ -96,6 +103,8 @@ void GameObject::RemoveFromWorld()
  931.      ///- Remove the gameobject from the accessor
  932.      if (IsInWorld())
  933.      {
  934. +        sEluna->OnRemoveFromWorld(this);
  935. +        
  936.          // Notify the outdoor pvp script
  937.          if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(GetZoneId()))
  938.              outdoorPvP->HandleGameObjectRemove(this);
  939. @@ -121,6 +130,15 @@ void GameObject::RemoveFromWorld()
  940.      Object::RemoveFromWorld();
  941.  }
  942.  
  943. +void GameObject::CleanupsBeforeDelete()
  944. +{
  945. +    if (m_uint32Values)
  946. +    {
  947. +        m_Events.KillAllEvents(false);
  948. +    }
  949. +    WorldObject::CleanupsBeforeDelete();
  950. +}
  951. +
  952.  bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, QuaternionData rotation, uint8 animprogress, GOState go_state)
  953.  {
  954.      MANGOS_ASSERT(map);
  955. @@ -187,6 +205,9 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
  956.          default:
  957.              break;
  958.      }
  959. +    
  960. +    // Used by Eluna
  961. +    sEluna->OnSpawn(this);
  962.  
  963.      // Notify the battleground or outdoor pvp script
  964.      if (map->IsBattleGroundOrArena())
  965. @@ -210,6 +231,10 @@ void GameObject::Update(uint32 update_diff, uint32 p_time)
  966.          //((Transport*)this)->Update(p_time);
  967.          return;
  968.      }
  969. +    
  970. +    m_Events.Update(p_time);
  971. +    // Used by Eluna
  972. +    sEluna->UpdateAI(this, p_time);
  973.  
  974.      switch (m_lootState)
  975.      {
  976. @@ -976,6 +1001,12 @@ void GameObject::Use(Unit* user)
  977.      Unit* spellCaster = user;
  978.      uint32 spellId = 0;
  979.      bool triggered = false;
  980. +    
  981. +    if (Player* playerUser = user->ToPlayer())
  982. +    {
  983. +        if (sScriptMgr.OnGossipHello(playerUser, this))
  984. +            return;
  985. +    }
  986.  
  987.      // test only for exist cooldown data (cooldown timer used for door/buttons reset that not have use cooldown)
  988.      if (uint32 cooldown = GetGOInfo()->GetCooldown())
  989. @@ -1790,12 +1821,14 @@ bool GameObject::IsFriendlyTo(Unit const* unit) const
  990.  void GameObject::SetLootState(LootState state)
  991.  {
  992.      m_lootState = state;
  993. +    sEluna->OnLootStateChanged(this, state);
  994.      UpdateCollisionState();
  995.  }
  996.  
  997.  void GameObject::SetGoState(GOState state)
  998.  {
  999.      SetByteValue(GAMEOBJECT_BYTES_1, 0, state);
  1000. +    sEluna->OnGameObjectStateChanged(this, state);
  1001.      UpdateCollisionState();
  1002.  }
  1003.  
  1004. @@ -2236,6 +2269,8 @@ void GameObject::ForceGameObjectHealth(int32 diff, Unit* caster)
  1005.      {
  1006.          DEBUG_FILTER_LOG(LOG_FILTER_DAMAGE, "DestructibleGO: %s taken damage %u dealt by %s", GetGuidStr().c_str(), uint32(-diff), caster->GetGuidStr().c_str());
  1007.  
  1008. +        if (caster && caster->ToPlayer())
  1009. +            sEluna->OnDamaged(this, caster->ToPlayer());
  1010.          if (m_useTimes > uint32(-diff))
  1011.              m_useTimes += diff;
  1012.          else
  1013. @@ -2274,6 +2309,8 @@ void GameObject::ForceGameObjectHealth(int32 diff, Unit* caster)
  1014.          {
  1015.              DEBUG_FILTER_LOG(LOG_FILTER_DAMAGE, "DestructibleGO: %s got destroyed", GetGuidStr().c_str());
  1016.  
  1017. +            if(caster && caster->ToPlayer())
  1018. +                sEluna->OnDestroyed(this, caster->ToPlayer());
  1019.              RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK_9 | GO_FLAG_UNK_10);
  1020.              SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK_11);
  1021.  
  1022. diff --git a/src/game/GameObject.h b/src/game/GameObject.h
  1023. index fb7547d..d440668 100644
  1024. --- a/src/game/GameObject.h
  1025. +++ b/src/game/GameObject.h
  1026. @@ -24,6 +24,7 @@
  1027.  #include "Object.h"
  1028.  #include "LootMgr.h"
  1029.  #include "Database/DatabaseEnv.h"
  1030. +#include "Utilities/EventProcessor.h"
  1031.  
  1032.  // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
  1033.  #if defined( __GNUC__ )
  1034. @@ -619,6 +620,8 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
  1035.  
  1036.          void AddToWorld() override;
  1037.          void RemoveFromWorld() override;
  1038. +        
  1039. +        void CleanupsBeforeDelete() override;
  1040.  
  1041.          bool Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang,
  1042.                      QuaternionData rotation = QuaternionData(), uint8 animprogress = GO_ANIMPROGRESS_DEFAULT, GOState go_state = GO_STATE_READY);
  1043. @@ -681,6 +684,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
  1044.                     (m_respawnTime == 0 && m_spawnedByDefault);
  1045.          }
  1046.          bool isSpawnedByDefault() const { return m_spawnedByDefault; }
  1047. +        void SetSpawnedByDefault(bool b) { m_spawnedByDefault = b; }
  1048.          uint32 GetRespawnDelay() const { return m_respawnDelayTime; }
  1049.          void Refresh();
  1050.          void Delete();
  1051. @@ -772,6 +776,9 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
  1052.          GridReference<GameObject>& GetGridRef() { return m_gridRef; }
  1053.  
  1054.          GameObjectModel* m_model;
  1055. +        
  1056. +        // Event Handler
  1057. +        EventProcessor m_Events;
  1058.  
  1059.      protected:
  1060.          uint32      m_spellId;
  1061. diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
  1062. index 3f47240..41d7661 100644
  1063. --- a/src/game/GridNotifiers.h
  1064. +++ b/src/game/GridNotifiers.h
  1065. @@ -216,6 +216,25 @@ namespace MaNGOS
  1066.      };
  1067.  
  1068.      template<class Check>
  1069. +    struct MANGOS_DLL_DECL WorldObjectLastSearcher
  1070. +    {
  1071. +        uint32 i_phaseMask;
  1072. +        WorldObject* &i_object;
  1073. +        Check& i_check;
  1074. +        
  1075. +        WorldObjectLastSearcher(WorldObject* & result, Check& check)
  1076. +        : i_phaseMask(check.GetFocusObject().GetPhaseMask()), i_object(result), i_check(check) {}
  1077. +        
  1078. +        void Visit(PlayerMapType& m);
  1079. +        void Visit(CreatureMapType& m);
  1080. +        void Visit(CorpseMapType& m);
  1081. +        void Visit(GameObjectMapType& m);
  1082. +        void Visit(DynamicObjectMapType& m);
  1083. +        
  1084. +        template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED>&) {}
  1085. +    };
  1086. +    
  1087. +    template<class Check>
  1088.      struct MANGOS_DLL_DECL WorldObjectListSearcher
  1089.      {
  1090.          uint32 i_phaseMask;
  1091. diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
  1092. index 7b714e5..eafe9dd 100644
  1093. --- a/src/game/GridNotifiersImpl.h
  1094. +++ b/src/game/GridNotifiersImpl.h
  1095. @@ -310,6 +310,86 @@ void MaNGOS::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType& m)
  1096.  }
  1097.  
  1098.  template<class Check>
  1099. +void MaNGOS::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType& m)
  1100. +{
  1101. +    for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
  1102. +    {
  1103. +        if (!itr->getSource()->InSamePhase(i_phaseMask))
  1104. +            continue;
  1105. +        
  1106. +        if (i_check(itr->getSource()))
  1107. +        {
  1108. +            i_object = itr->getSource();
  1109. +            return;
  1110. +        }
  1111. +    }
  1112. +}
  1113. +
  1114. +template<class Check>
  1115. +void MaNGOS::WorldObjectLastSearcher<Check>::Visit(PlayerMapType& m)
  1116. +{
  1117. +    for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
  1118. +    {
  1119. +        if (!itr->getSource()->InSamePhase(i_phaseMask))
  1120. +            continue;
  1121. +        
  1122. +        if (i_check(itr->getSource()))
  1123. +        {
  1124. +            i_object = itr->getSource();
  1125. +            return;
  1126. +        }
  1127. +    }
  1128. +}
  1129. +
  1130. +template<class Check>
  1131. +void MaNGOS::WorldObjectLastSearcher<Check>::Visit(CreatureMapType& m)
  1132. +{
  1133. +    for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
  1134. +    {
  1135. +        if (!itr->getSource()->InSamePhase(i_phaseMask))
  1136. +            continue;
  1137. +        
  1138. +        if (i_check(itr->getSource()))
  1139. +        {
  1140. +            i_object = itr->getSource();
  1141. +            return;
  1142. +        }
  1143. +    }
  1144. +}
  1145. +
  1146. +template<class Check>
  1147. +void MaNGOS::WorldObjectLastSearcher<Check>::Visit(CorpseMapType& m)
  1148. +{
  1149. +    for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
  1150. +    {
  1151. +        if (!itr->getSource()->InSamePhase(i_phaseMask))
  1152. +            continue;
  1153. +        
  1154. +        if (i_check(itr->getSource()))
  1155. +        {
  1156. +            i_object = itr->getSource();
  1157. +            return;
  1158. +        }
  1159. +    }
  1160. +}
  1161. +
  1162. +template<class Check>
  1163. +void MaNGOS::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType& m)
  1164. +{
  1165. +    for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
  1166. +    {
  1167. +        if (!itr->getSource()->InSamePhase(i_phaseMask))
  1168. +            continue;
  1169. +        
  1170. +        if (i_check(itr->getSource()))
  1171. +        {
  1172. +            i_object = itr->getSource();
  1173. +            return;
  1174. +        }
  1175. +    }
  1176. +}
  1177. +
  1178. +template<class Check>
  1179.  void MaNGOS::WorldObjectListSearcher<Check>::Visit(PlayerMapType& m)
  1180.  {
  1181.      for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
  1182. diff --git a/src/game/Group.cpp b/src/game/Group.cpp
  1183. index 7b93500..bc6f5f1 100644
  1184. --- a/src/game/Group.cpp
  1185. +++ b/src/game/Group.cpp
  1186. @@ -33,6 +33,7 @@
  1187.  #include "MapPersistentStateMgr.h"
  1188.  #include "Util.h"
  1189.  #include "LootMgr.h"
  1190. +#include "LuaEngine.h"
  1191.  
  1192.  #define LOOT_ROLL_TIMEOUT  (1*MINUTE*IN_MILLISECONDS)
  1193.  
  1194. @@ -83,6 +84,8 @@ Group::Group() : m_Id(0), m_groupType(GROUPTYPE_NORMAL),
  1195.  
  1196.  Group::~Group()
  1197.  {
  1198. +    Eluna::RemoveRef(this);
  1199. +    
  1200.      if (m_bgGroup)
  1201.      {
  1202.          DEBUG_LOG("Group::~Group: battleground group being deleted.");
  1203. @@ -163,6 +166,9 @@ bool Group::Create(ObjectGuid guid, const char* name)
  1204.  
  1205.      if (!isBGGroup())
  1206.          CharacterDatabase.CommitTransaction();
  1207. +    
  1208. +    // Used by Eluna
  1209. +    sEluna->OnCreate(this, m_leaderGuid, m_groupType);
  1210.  
  1211.      return true;
  1212.  }
  1213. @@ -255,6 +261,9 @@ bool Group::AddInvite(Player* player)
  1214.      m_invitees.insert(player);
  1215.  
  1216.      player->SetGroupInvite(this);
  1217. +    
  1218. +    // Used by Eluna
  1219. +    sEluna->OnInviteMember(this, player->GetObjectGuid());
  1220.  
  1221.      return true;
  1222.  }
  1223. @@ -336,6 +345,9 @@ bool Group::AddMember(ObjectGuid guid, const char* name)
  1224.          }
  1225.          player->SetGroupUpdateFlag(GROUP_UPDATE_FULL);
  1226.          UpdatePlayerOutOfRange(player);
  1227. +        
  1228. +        // Used by Eluna
  1229. +        sEluna->OnAddMember(this, player->GetObjectGuid());
  1230.  
  1231.          // quest related GO state dependent from raid membership
  1232.          if (isRaidGroup())
  1233. @@ -394,6 +406,9 @@ uint32 Group::RemoveMember(ObjectGuid guid, uint8 method)
  1234.      // if group before remove <= 2 disband it
  1235.      else
  1236.          Disband(true);
  1237. +    
  1238. +    // Used by Eluna
  1239. +    sEluna->OnRemoveMember(this, guid, method); // Kicker and Reason not a part of Mangos, implement?
  1240.  
  1241.      return m_memberSlots.size();
  1242.  }
  1243. @@ -403,6 +418,9 @@ void Group::ChangeLeader(ObjectGuid guid)
  1244.      member_citerator slot = _getMemberCSlot(guid);
  1245.      if (slot == m_memberSlots.end())
  1246.          return;
  1247. +    
  1248. +    // Used by Eluna
  1249. +    sEluna->OnChangeLeader(this, guid, GetLeaderGuid());
  1250.  
  1251.      _setLeader(guid);
  1252.  
  1253. @@ -478,6 +496,9 @@ void Group::Disband(bool hideDestroy)
  1254.          ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
  1255.          ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
  1256.      }
  1257. +    
  1258. +    // Used by Eluna
  1259. +    sEluna->OnDisband(this);
  1260.  
  1261.      m_leaderGuid.Clear();
  1262.      m_leaderName = "";
  1263. diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp
  1264. index a6ab775..7fa1ba7 100644
  1265. --- a/src/game/Guild.cpp
  1266. +++ b/src/game/Guild.cpp
  1267. @@ -30,6 +30,7 @@
  1268.  #include "Language.h"
  1269.  #include "World.h"
  1270.  #include "Calendar.h"
  1271. +#include "LuaEngine.h"
  1272.  
  1273.  //// MemberSlot ////////////////////////////////////////////
  1274.  void MemberSlot::SetMemberStats(Player* player)
  1275. @@ -101,6 +102,8 @@ Guild::Guild()
  1276.  
  1277.  Guild::~Guild()
  1278.  {
  1279. +    Eluna::RemoveRef(this);
  1280. +    
  1281.      DeleteGuildBankItems();
  1282.  }
  1283.  
  1284. @@ -140,6 +143,9 @@ bool Guild::Create(Player* leader, std::string gname)
  1285.      CharacterDatabase.CommitTransaction();
  1286.  
  1287.      CreateDefaultGuildRanks(lSession->GetSessionDbLocaleIndex());
  1288. +    
  1289. +    // Used by Eluna
  1290. +    sEluna->OnCreate(this, leader, gname.c_str());
  1291.  
  1292.      return AddMember(m_LeaderGuid, (uint32)GR_GUILDMASTER);
  1293.  }
  1294. @@ -240,6 +246,9 @@ bool Guild::AddMember(ObjectGuid plGuid, uint32 plRank)
  1295.      }
  1296.  
  1297.      UpdateAccountsNumber();
  1298. +    
  1299. +    // Used by Eluna
  1300. +    sEluna->OnAddMember(this, pl, newmember.RankId);
  1301.  
  1302.      return true;
  1303.  }
  1304. @@ -251,6 +260,9 @@ void Guild::SetMOTD(std::string motd)
  1305.      // motd now can be used for encoding to DB
  1306.      CharacterDatabase.escape_string(motd);
  1307.      CharacterDatabase.PExecute("UPDATE guild SET motd='%s' WHERE guildid='%u'", motd.c_str(), m_Id);
  1308. +
  1309. +    // Used by Eluna
  1310. +    sEluna->OnMOTDChanged(this, motd);
  1311.  }
  1312.  
  1313.  void Guild::SetGINFO(std::string ginfo)
  1314. @@ -260,6 +272,9 @@ void Guild::SetGINFO(std::string ginfo)
  1315.      // ginfo now can be used for encoding to DB
  1316.      CharacterDatabase.escape_string(ginfo);
  1317.      CharacterDatabase.PExecute("UPDATE guild SET info='%s' WHERE guildid='%u'", ginfo.c_str(), m_Id);
  1318. +
  1319. +    // Used by Eluna
  1320. +    sEluna->OnInfoChanged(this, ginfo);
  1321.  }
  1322.  
  1323.  bool Guild::LoadGuildFromDB(QueryResult* guildDataResult)
  1324. @@ -554,10 +569,25 @@ bool Guild::DelMember(ObjectGuid guid, bool isDisbanding)
  1325.  
  1326.      if (!isDisbanding)
  1327.          UpdateAccountsNumber();
  1328. +    
  1329. +    // Used by Eluna
  1330. +     sEluna->OnRemoveMember(this, player, isDisbanding); // IsKicked not a part of Mangos, implement?
  1331.  
  1332.      return members.empty();
  1333.  }
  1334.  
  1335. +bool Guild::ChangeMemberRank(ObjectGuid guid, uint8 newRank)
  1336. +{
  1337. +    if (newRank <= GetLowestRank()) // Validate rank (allow only existing ranks)
  1338. +        if (MemberSlot* member = GetMemberSlot(guid))
  1339. +        {
  1340. +            member->ChangeRank(newRank);
  1341. +            return true;
  1342. +        }
  1343. +        
  1344. +    return false;
  1345. +}
  1346. +
  1347.  void Guild::BroadcastToGuild(WorldSession* session, const std::string& msg, uint32 language)
  1348.  {
  1349.      if (session && session->GetPlayer() && HasRankRight(session->GetPlayer()->GetRank(), GR_RIGHT_GCHATSPEAK))
  1350. @@ -755,6 +785,10 @@ void Guild::Disband()
  1351.      CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id);
  1352.      CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE guildid = '%u'", m_Id);
  1353.      CharacterDatabase.CommitTransaction();
  1354. +    
  1355. +    // Used by Eluna
  1356. +    sEluna->OnDisband(this);
  1357. +    
  1358.      sGuildMgr.RemoveGuild(m_Id);
  1359.  }
  1360.  
  1361. @@ -1268,6 +1302,11 @@ bool Guild::MemberMoneyWithdraw(uint32 amount, uint32 LowGuid)
  1362.          CharacterDatabase.PExecute("UPDATE guild_member SET BankRemMoney='%u' WHERE guildid='%u' AND guid='%u'",
  1363.                                     itr->second.BankRemMoney, m_Id, LowGuid);
  1364.      }
  1365. +    
  1366. +    // Used by Eluna
  1367. +    Player* player = sObjectMgr.GetPlayer(ObjectGuid(HIGHGUID_PLAYER, LowGuid));
  1368. +    sEluna->OnMemberWitdrawMoney(this, player, amount, false); // IsRepair not a part of Mangos, implement?
  1369. +    
  1370.      return true;
  1371.  }
  1372.  
  1373. @@ -1656,6 +1695,9 @@ void Guild::LogBankEvent(uint8 EventType, uint8 TabId, uint32 PlayerGuidLow, uin
  1374.  
  1375.          m_GuildBankEventLog_Item[TabId].push_back(NewEvent);
  1376.      }
  1377. +    
  1378. +    // Used by Eluna
  1379. +    sEluna->OnBankEvent(this, EventType, TabId, PlayerGuidLow, ItemOrMoney, ItemStackCount, DestTabId);
  1380.  
  1381.      // save event to database
  1382.      CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid='%u' AND LogGuid='%u' AND TabId='%u'", m_Id, currentLogGuid, currentTabId);
  1383. diff --git a/src/game/Guild.h b/src/game/Guild.h
  1384. index 02792a7..7d5cbbf 100644
  1385. --- a/src/game/Guild.h
  1386. +++ b/src/game/Guild.h
  1387. @@ -29,6 +29,7 @@
  1388.  
  1389.  class Item;
  1390.  
  1391. +#define GUILD_RANK_NONE         0xFF
  1392.  #define GUILD_RANKS_MIN_COUNT   5
  1393.  #define GUILD_RANKS_MAX_COUNT   10
  1394.  
  1395. @@ -324,6 +325,7 @@ class Guild
  1396.          void SetLeader(ObjectGuid guid);
  1397.          bool AddMember(ObjectGuid plGuid, uint32 plRank);
  1398.          bool DelMember(ObjectGuid guid, bool isDisbanding = false);
  1399. +        bool ChangeMemberRank(ObjectGuid guid, uint8 newRank);
  1400.          // lowest rank is the count of ranks - 1 (the highest rank_id in table)
  1401.          uint32 GetLowestRank() const { return m_Ranks.size() - 1; }
  1402.  
  1403. diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp
  1404. index fbe814e..7e28881 100644
  1405. --- a/src/game/GuildHandler.cpp
  1406. +++ b/src/game/GuildHandler.cpp
  1407. @@ -28,6 +28,7 @@
  1408.  #include "GossipDef.h"
  1409.  #include "SocialMgr.h"
  1410.  #include "Calendar.h"
  1411. +#include "LuaEngine.h"
  1412.  
  1413.  void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
  1414.  {
  1415. @@ -65,6 +66,17 @@ void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
  1416.      sGuildMgr.AddGuild(guild);
  1417.  }
  1418.  
  1419. +void WorldSession::SendGuildInvite(Player* player, bool alreadyInGuild /*= false*/)
  1420. +{
  1421. +    Guild* guild = sGuildMgr.GetGuildById(GetPlayer()->GetGuildId());
  1422. +    player->SetGuildIdInvited(GetPlayer()->GetGuildId());
  1423. +    
  1424. +    WorldPacket data(SMSG_GUILD_INVITE, (8 + 10)); // guess size
  1425. +    data << GetPlayer()->GetName();
  1426. +    data << guild->GetName();
  1427. +    player->GetSession()->SendPacket(&data);       // unk
  1428. +}
  1429. +
  1430.  void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
  1431.  {
  1432.      DEBUG_LOG("WORLD: Received opcode CMSG_GUILD_INVITE");
  1433. @@ -917,6 +929,9 @@ void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recv_data)
  1434.      // log
  1435.      pGuild->LogBankEvent(GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), GetPlayer()->GetGUIDLow(), money);
  1436.  
  1437. +    // Used by Eluna
  1438. +    sEluna->OnMemberDepositMoney(pGuild, GetPlayer(), money);
  1439. +    
  1440.      pGuild->DisplayGuildBankTabsInfo(this);
  1441.      pGuild->DisplayGuildBankContent(this, 0);
  1442.      pGuild->DisplayGuildBankMoneyUpdate(this);
  1443. diff --git a/src/game/Item.cpp b/src/game/Item.cpp
  1444. index 4de0aac..a73a737 100644
  1445. --- a/src/game/Item.cpp
  1446. +++ b/src/game/Item.cpp
  1447. @@ -23,6 +23,7 @@
  1448.  #include "Database/DatabaseEnv.h"
  1449.  #include "ItemEnchantmentMgr.h"
  1450.  #include "SQLStorages.h"
  1451. +#include "LuaEngine.h"
  1452.  
  1453.  void AddItemsSetItem(Player* player, Item* item)
  1454.  {
  1455. @@ -247,6 +248,11 @@ Item::Item() :
  1456.      m_lootState = ITEM_LOOT_NONE;
  1457.  }
  1458.  
  1459. +Item::~Item()
  1460. +{
  1461. +    Eluna::RemoveRef(this);
  1462. +}
  1463. +
  1464.  bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
  1465.  {
  1466.      Object::_Create(guidlow, 0, HIGHGUID_ITEM);
  1467. @@ -273,6 +279,13 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
  1468.      return true;
  1469.  }
  1470.  
  1471. +bool Item::IsNotEmptyBag() const
  1472. +{
  1473. +    if (Bag const* bag = ToBag())
  1474. +        return !bag->IsEmpty();
  1475. +    return false;
  1476. +}
  1477. +
  1478.  void Item::UpdateDuration(Player* owner, uint32 diff)
  1479.  {
  1480.      if (!GetUInt32Value(ITEM_FIELD_DURATION))
  1481. @@ -282,6 +295,9 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
  1482.  
  1483.      if (GetUInt32Value(ITEM_FIELD_DURATION) <= diff)
  1484.      {
  1485. +        // Used by Eluna
  1486. +        sEluna->OnExpire(owner, GetProto());
  1487. +        
  1488.          if (uint32 newItemId = sObjectMgr.GetItemExpireConvert(GetEntry()))
  1489.              owner->ConvertItem(this, newItemId);
  1490.          else
  1491. diff --git a/src/game/Item.h b/src/game/Item.h
  1492. index c86afa1..194ea68 100644
  1493. --- a/src/game/Item.h
  1494. +++ b/src/game/Item.h
  1495. @@ -277,6 +277,7 @@ class MANGOS_DLL_SPEC Item : public Object
  1496.          Item* CloneItem(uint32 count, Player const* player = NULL) const;
  1497.  
  1498.          Item();
  1499. +        ~Item();
  1500.  
  1501.          virtual bool Create(uint32 guidlow, uint32 itemid, Player const* owner);
  1502.  
  1503. @@ -297,7 +298,13 @@ class MANGOS_DLL_SPEC Item : public Object
  1504.          void DeleteFromInventoryDB();
  1505.          void LoadLootFromDB(Field* fields);
  1506.  
  1507. +        Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return NULL; }
  1508. +        const Bag* ToBag() const { if (IsBag()) return reinterpret_cast<const Bag*>(this); else return NULL; }
  1509. +        
  1510. +        bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_UNLOCKED); }
  1511.          bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
  1512. +        bool IsCurrencyToken() const { return GetProto()->IsCurrencyToken(); }
  1513. +        bool IsNotEmptyBag() const;
  1514.          bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
  1515.          bool CanBeTraded(bool mail = false) const;
  1516.          void SetInTrade(bool b = true) { mb_in_trade = b; }
  1517. @@ -378,7 +385,9 @@ class MANGOS_DLL_SPEC Item : public Object
  1518.          bool HasInvolvedQuest(uint32 /*quest_id*/) const override { return false; }
  1519.          bool IsPotion() const { return GetProto()->IsPotion(); }
  1520.          bool IsConjuredConsumable() const { return GetProto()->IsConjuredConsumable(); }
  1521. -
  1522. +        bool IsWeaponVellum() const { return GetProto()->IsWeaponVellum(); }
  1523. +        bool IsArmorVellum() const { return GetProto()->IsArmorVellum(); }
  1524. +      
  1525.          void AddToClientUpdateList() override;
  1526.          void RemoveFromClientUpdateList() override;
  1527.          void BuildUpdateData(UpdateDataMapType& update_players) override;
  1528. diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h
  1529. index 1a60d8c..54f4ce0 100644
  1530. --- a/src/game/ItemPrototype.h
  1531. +++ b/src/game/ItemPrototype.h
  1532. @@ -638,6 +638,8 @@ struct ItemPrototype
  1533.  
  1534.          return false;
  1535.      }
  1536. +    
  1537. +    bool IsCurrencyToken() const { return BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS; }
  1538.  
  1539.      uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF - 1); }
  1540.  
  1541. @@ -670,6 +672,9 @@ struct ItemPrototype
  1542.      {
  1543.          return (Class == ITEM_CLASS_TRADE_GOODS && (1 << SubClass) & (1 << ITEM_SUBCLASS_ARMOR_ENCHANTMENT | 1 << ITEM_SUBCLASS_WEAPON_ENCHANTMENT));
  1544.      }
  1545. +    
  1546. +    bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; }
  1547. +    bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; }
  1548.  };
  1549.  
  1550.  // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
  1551. diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp
  1552. index 3756e9a..4dc97b2 100644
  1553. --- a/src/game/LootHandler.cpp
  1554. +++ b/src/game/LootHandler.cpp
  1555. @@ -31,6 +31,7 @@
  1556.  #include "World.h"
  1557.  #include "Util.h"
  1558.  #include "DBCStores.h"
  1559. +#include "LuaEngine.h"
  1560.  
  1561.  void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recv_data)
  1562.  {
  1563. @@ -275,6 +276,9 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recv_data*/)
  1564.              data << uint8(1);                               // 1 is "you loot..."
  1565.              player->GetSession()->SendPacket(&data);
  1566.          }
  1567. +        
  1568. +        // Used by Eluna
  1569. +        sEluna->OnLootMoney(player, pLoot->gold);
  1570.  
  1571.          pLoot->gold = 0;
  1572.  
  1573. @@ -575,6 +579,9 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recv_data)
  1574.      target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, pLoot->loot_type, item.count);
  1575.      target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count);
  1576.  
  1577. +    // Used by Eluna
  1578. +    sEluna->OnLootItem(target, newitem, item.count, lootguid);
  1579. +    
  1580.      // mark as looted
  1581.      item.count = 0;
  1582.      item.is_looted = true;
  1583. diff --git a/src/game/Map.cpp b/src/game/Map.cpp
  1584. index 82d7352..3aec8f7 100644
  1585. --- a/src/game/Map.cpp
  1586. +++ b/src/game/Map.cpp
  1587. @@ -39,9 +39,13 @@
  1588.  #include "BattleGround/BattleGroundMgr.h"
  1589.  #include "Calendar.h"
  1590.  #include "Chat.h"
  1591. +#include "LuaEngine.h"
  1592.  
  1593.  Map::~Map()
  1594.  {
  1595. +    sEluna->OnDestroy(this);
  1596. +    Eluna::RemoveRef(this);
  1597. +    
  1598.      UnloadAll(true);
  1599.  
  1600.      if (!m_scriptSchedule.empty())
  1601. @@ -99,6 +103,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
  1602.  
  1603.      m_persistentState = sMapPersistentStateMgr.AddPersistentState(i_mapEntry, GetInstanceId(), GetDifficulty(), 0, IsDungeon());
  1604.      m_persistentState->SetUsedByMapState(this);
  1605. +    
  1606. +    sEluna->OnCreate(this);
  1607.  }
  1608.  
  1609.  void Map::InitVisibilityDistance()
  1610. @@ -300,6 +306,9 @@ bool Map::Add(Player* player)
  1611.      NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
  1612.      player->GetViewPoint().Event_AddedToWorld(&(*grid)(cell.CellX(), cell.CellY()));
  1613.      UpdateObjectVisibility(player, cell, p);
  1614. +    
  1615. +    sEluna->OnMapChanged(player);
  1616. +    sEluna->OnPlayerEnter(this, player);
  1617.  
  1618.      if (i_data)
  1619.          i_data->OnPlayerEnter(player);
  1620. @@ -563,12 +572,16 @@ void Map::Update(const uint32& t_diff)
  1621.      if (!m_scriptSchedule.empty())
  1622.          ScriptsProcess();
  1623.  
  1624. +    sEluna->OnUpdate(this, t_diff);
  1625. +    
  1626.      if (i_data)
  1627.          i_data->Update(t_diff);
  1628.  }
  1629.  
  1630.  void Map::Remove(Player* player, bool remove)
  1631.  {
  1632. +    sEluna->OnPlayerLeave(this, player);
  1633. +    
  1634.      if (i_data)
  1635.          i_data->OnPlayerLeave(player);
  1636.  
  1637. @@ -982,6 +995,11 @@ void Map::AddObjectToRemoveList(WorldObject* obj)
  1638.  {
  1639.      MANGOS_ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId());
  1640.  
  1641. +    if (Creature* creature = obj->ToCreature())
  1642. +        sEluna->OnRemove(creature);
  1643. +    else if (GameObject* gameobject = obj->ToGameObject())
  1644. +        sEluna->OnRemove(gameobject);
  1645. +    
  1646.      obj->CleanupsBeforeDelete();                            // remove or simplify at least cross referenced links
  1647.  
  1648.      i_objectsToRemove.insert(obj);
  1649. diff --git a/src/game/Map.h b/src/game/Map.h
  1650. index 0c2e77e..b2aea60 100644
  1651. --- a/src/game/Map.h
  1652. +++ b/src/game/Map.h
  1653. @@ -191,6 +191,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
  1654.          // NOTE: this duplicate of Instanceable(), but Instanceable() can be changed when BG also will be instanceable
  1655.          bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
  1656.          bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
  1657. +        bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; }
  1658.          bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); }
  1659.          bool IsRaidOrHeroicDungeon() const { return IsRaid() || GetDifficulty() > DUNGEON_DIFFICULTY_NORMAL; }
  1660.          bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }
  1661. diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
  1662. index 2bdb6a7..46fc2a1 100644
  1663. --- a/src/game/MiscHandler.cpp
  1664. +++ b/src/game/MiscHandler.cpp
  1665. @@ -42,6 +42,7 @@
  1666.  #include "Pet.h"
  1667.  #include "SocialMgr.h"
  1668.  #include "DBCEnums.h"
  1669. +#include "LuaEngine.h"
  1670.  
  1671.  void WorldSession::HandleRepopRequestOpcode(WorldPacket& recv_data)
  1672.  {
  1673. @@ -62,6 +63,9 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket& recv_data)
  1674.          DEBUG_LOG("HandleRepopRequestOpcode: got request after player %s(%d) was killed and before he was updated", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
  1675.          GetPlayer()->KillPlayer();
  1676.      }
  1677. +    
  1678. +    // Used by Eluna
  1679. +    sEluna->OnRepop(GetPlayer());
  1680.  
  1681.      // this is spirit release confirm?
  1682.      GetPlayer()->RemovePet(PET_SAVE_REAGENTS);
  1683. diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp
  1684. index 2f3717f..24af752 100644
  1685. --- a/src/game/NPCHandler.cpp
  1686. +++ b/src/game/NPCHandler.cpp
  1687. @@ -34,6 +34,8 @@
  1688.  #include "Guild.h"
  1689.  #include "GuildMgr.h"
  1690.  #include "Chat.h"
  1691. +#include "Item.h"
  1692. +#include "LuaEngine.h"
  1693.  
  1694.  enum StableResultCode
  1695.  {
  1696. @@ -392,6 +394,29 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recv_data)
  1697.          if (!sScriptMgr.OnGossipSelect(_player, pGo, sender, action, code.empty() ? NULL : code.c_str()))
  1698.              _player->OnGossipSelect(pGo, gossipListId, menuId);
  1699.      }
  1700. +    else if (guid.IsItem())
  1701. +    {
  1702. +        Item* item = GetPlayer()->GetItemByGuid(guid);
  1703. +        if (!item)
  1704. +        {
  1705. +            DEBUG_LOG("WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", guid.GetString().c_str());
  1706. +            return;
  1707. +        }
  1708. +        
  1709. +        // Used by Eluna
  1710. +        sEluna->HandleGossipSelectOption(GetPlayer(), item, GetPlayer()->PlayerTalkClass->GossipOptionSender(gossipListId), GetPlayer()->PlayerTalkClass->GossipOptionAction(gossipListId), code);
  1711. +    }
  1712. +    else if (guid.IsPlayer())
  1713. +    {
  1714. +        if (GetPlayer()->GetGUIDLow() != guid || GetPlayer()->PlayerTalkClass->GetGossipMenu().GetMenuId() != menuId)
  1715. +        {
  1716. +            DEBUG_LOG("WORLD: HandleGossipSelectOptionOpcode - %s not found or you can't interact with it.", guid.GetString().c_str());
  1717. +            return;
  1718. +        }
  1719. +        
  1720. +        // Used by Eluna
  1721. +        sEluna->HandleGossipSelectOption(GetPlayer(), menuId, GetPlayer()->PlayerTalkClass->GossipOptionSender(gossipListId), GetPlayer()->PlayerTalkClass->GossipOptionAction(gossipListId), code);
  1722. +    }
  1723.  }
  1724.  
  1725.  void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket& recv_data)
  1726. diff --git a/src/game/Object.cpp b/src/game/Object.cpp
  1727. index a39b808..576bd9a 100644
  1728. --- a/src/game/Object.cpp
  1729. +++ b/src/game/Object.cpp
  1730. @@ -44,6 +44,7 @@
  1731.  #include "movement/packet_builder.h"
  1732.  #include "CreatureLinkingMgr.h"
  1733.  #include "Chat.h"
  1734. +#include "LuaEngine.h"
  1735.  
  1736.  Object::Object()
  1737.  {
  1738. @@ -59,6 +60,8 @@ Object::Object()
  1739.  
  1740.  Object::~Object()
  1741.  {
  1742. +    Eluna::RemoveRef(this);
  1743. +    
  1744.      if (IsInWorld())
  1745.      {
  1746.          ///- Do NOT call RemoveFromWorld here, if the object is a player it will crash
  1747. @@ -677,6 +680,14 @@ void Object::SetUInt32Value(uint16 index, uint32 value)
  1748.      }
  1749.  }
  1750.  
  1751. +void Object::UpdateUInt32Value(uint16 index, uint32 value)
  1752. +{
  1753. +    MANGOS_ASSERT(index < m_valuesCount || PrintIndexError(index, true));
  1754. +    
  1755. +    m_uint32Values[index] = value;
  1756. +    m_changedValues[index] = true;
  1757. +}
  1758. +
  1759.  void Object::SetUInt64Value(uint16 index, const uint64& value)
  1760.  {
  1761.      MANGOS_ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
  1762. @@ -944,6 +955,11 @@ WorldObject::WorldObject() :
  1763.  {
  1764.  }
  1765.  
  1766. +WorldObject::~WorldObject()
  1767. +{
  1768. +    Eluna::RemoveRef(this);
  1769. +}
  1770. +
  1771.  void WorldObject::CleanupsBeforeDelete()
  1772.  {
  1773.      RemoveFromWorld();
  1774. @@ -1582,6 +1598,9 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
  1775.  
  1776.      if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
  1777.          ((Creature*)this)->AI()->JustSummoned(pCreature);
  1778. +    
  1779. +    if (Unit* summoner = ToUnit())
  1780. +        sEluna->OnSummoned(pCreature, summoner);
  1781.  
  1782.      // Creature Linking, Initial load is handled like respawn
  1783.      if (pCreature->IsLinkingEventTrigger())
  1784. @@ -1591,6 +1610,28 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
  1785.      return pCreature;
  1786.  }
  1787.  
  1788. +GameObject* WorldObject::SummonGameObject(uint32 id, float x, float y, float z, float angle, uint32 despwtime)
  1789. +{
  1790. +    GameObject* pGameObj = new GameObject;
  1791. +    
  1792. +    Map *map = GetMap();
  1793. +    
  1794. +    if(!map)
  1795. +        return NULL;
  1796. +    
  1797. +    if (!pGameObj->Create(map->GenerateLocalLowGuid(HIGHGUID_GAMEOBJECT), id, map, GetPhaseMask(), x, y, z, angle))
  1798. +    {
  1799. +        delete pGameObj;
  1800. +        return NULL;
  1801. +    }
  1802. +    
  1803. +    pGameObj->SetRespawnTime(despwtime/IN_MILLISECONDS);
  1804. +    
  1805. +    map->Add(pGameObj);
  1806. +    
  1807. +    return pGameObj;
  1808. +}
  1809. +
  1810.  // how much space should be left in front of/ behind a mob that already uses a space
  1811.  #define OCCUPY_POS_DEPTH_FACTOR                          1.8f
  1812.  
  1813. diff --git a/src/game/Object.h b/src/game/Object.h
  1814. index d1def09..fa89d70 100644
  1815. --- a/src/game/Object.h
  1816. +++ b/src/game/Object.h
  1817. @@ -66,6 +66,7 @@ class WorldPacket;
  1818.  class UpdateData;
  1819.  class WorldSession;
  1820.  class Creature;
  1821. +class GameObject;
  1822.  class Player;
  1823.  class Unit;
  1824.  class Group;
  1825. @@ -216,8 +217,28 @@ class MANGOS_DLL_SPEC Object
  1826.  
  1827.          ObjectGuid const& GetGuidValue(uint16 index) const { return *reinterpret_cast<ObjectGuid const*>(&GetUInt64Value(index)); }
  1828.  
  1829. +        Player* ToPlayer() { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return NULL; }
  1830. +        Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player const*>(this); else return NULL; }
  1831. +
  1832. +        Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return NULL; }
  1833. +        Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature const*>(this); else return NULL; }
  1834. +
  1835. +        Unit* ToUnit() { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit*>(this); else return NULL; }
  1836. +        Unit const* ToUnit() const { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit const*>(this); else return NULL; }
  1837. +
  1838. +        GameObject* ToGameObject() { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(this); else return NULL; }
  1839. +        GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject const*>(this); else return NULL; }
  1840. +
  1841. +        Corpse* ToCorpse() { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(this); else return NULL; }
  1842. +        Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse const*>(this); else return NULL; }
  1843. +
  1844. +        DynamicObject* ToDynObject() { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject*>(this); else return NULL; }
  1845. +        DynamicObject const* ToDynObject() const { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject const*>(this); else return NULL; }
  1846. +
  1847. +        
  1848.          void SetInt32Value(uint16 index,        int32  value);
  1849.          void SetUInt32Value(uint16 index,       uint32  value);
  1850. +        void UpdateUInt32Value(uint16 index, uint32 value);
  1851.          void SetUInt64Value(uint16 index, const uint64& value);
  1852.          void SetFloatValue(uint16 index,       float   value);
  1853.          void SetByteValue(uint16 index, uint8 offset, uint8 value);
  1854. @@ -435,7 +456,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
  1855.                  WorldObject* const m_obj;
  1856.          };
  1857.  
  1858. -        virtual ~WorldObject() {}
  1859. +        virtual ~WorldObject();
  1860.  
  1861.          virtual void Update(uint32 /*update_diff*/, uint32 /*time_diff*/) {}
  1862.  
  1863. @@ -604,7 +625,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object
  1864.          void BuildUpdateData(UpdateDataMapType&) override;
  1865.  
  1866.          Creature* SummonCreature(uint32 id, float x, float y, float z, float ang, TempSummonType spwtype, uint32 despwtime, bool asActiveObject = false);
  1867. -
  1868. +        GameObject* SummonGameObject(uint32 id, float x, float y, float z, float angle, uint32 despwtime);
  1869. +        
  1870.          bool isActiveObject() const { return m_isActiveObject || m_viewPoint.hasViewers(); }
  1871.          void SetActiveObjectState(bool active);
  1872.  
  1873. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
  1874. index 17b7310..18d9d64 100755
  1875. --- a/src/game/ObjectMgr.cpp
  1876. +++ b/src/game/ObjectMgr.cpp
  1877. @@ -223,6 +223,17 @@ ArenaTeam* ObjectMgr::GetArenaTeamByCaptain(ObjectGuid guid) const
  1878.      return NULL;
  1879.  }
  1880.  
  1881. +void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data)
  1882. +{
  1883. +    if (!s.empty())
  1884. +    {
  1885. +        if (data.size() <= size_t(locale))
  1886. +            data.resize(locale + 1);
  1887. +        
  1888. +        data[locale] = s;
  1889. +    }
  1890. +}
  1891. +
  1892.  void ObjectMgr::LoadCreatureLocales()
  1893.  {
  1894.      mCreatureLocaleMap.clear();                             // need for reload case
  1895. @@ -6933,11 +6944,15 @@ void ObjectMgr::LoadNPCSpellClickSpells()
  1896.              continue;
  1897.          }
  1898.  
  1899. -        SpellEntry const* spellinfo = sSpellStore.LookupEntry(info.spellId);
  1900. -        if (!spellinfo)
  1901. +        // spell can be 0 for special or custom cases
  1902. +        if(info.spellId)
  1903.          {
  1904. -            sLog.outErrorDb("Table npc_spellclick_spells references unknown spellid %u. Skipping entry.", info.spellId);
  1905. -            continue;
  1906. +            SpellEntry const* spellinfo = sSpellStore.LookupEntry(info.spellId);
  1907. +            if (!spellinfo)
  1908. +            {
  1909. +                sLog.outErrorDb("Table npc_spellclick_spells references unknown spellid %u. Skipping entry.", info.spellId);
  1910. +                continue;
  1911. +            }
  1912.          }
  1913.  
  1914.          if (info.conditionId && !sConditionStorage.LookupEntry<PlayerCondition const*>(info.conditionId))
  1915. diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
  1916. index 31077b1..910e7fc 100755
  1917. --- a/src/game/ObjectMgr.h
  1918. +++ b/src/game/ObjectMgr.h
  1919. @@ -117,7 +117,7 @@ typedef UNORDERED_MAP < uint32/*(mapid,spawnMode) pair*/, CellObjectGuidsMap > M
  1920.  
  1921.  // mangos string ranges
  1922.  #define MIN_MANGOS_STRING_ID           1                    // 'mangos_string'
  1923. -#define MAX_MANGOS_STRING_ID           2001000000
  1924. +#define MAX_MANGOS_STRING_ID           2000000000
  1925.  #define MIN_DB_SCRIPT_STRING_ID        MAX_MANGOS_STRING_ID // 'db_script_string'
  1926.  #define MAX_DB_SCRIPT_STRING_ID        2000010000
  1927.  #define MIN_CREATURE_AI_TEXT_STRING_ID (-1)                 // 'creature_ai_texts'
  1928. @@ -1043,6 +1043,13 @@ class ObjectMgr
  1929.          bool RemoveVendorItem(uint32 entry, uint32 item);
  1930.          bool IsVendorItemValid(bool isTemplate, char const* tableName, uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, uint16 conditionId, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL) const;
  1931.  
  1932. +        static void AddLocaleString(std::string const& s, LocaleConstant locale, StringVector& data);
  1933. +        static inline void GetLocaleString(const StringVector& data, int loc_idx, std::string& value)
  1934. +        {
  1935. +            if (data.size() > size_t(loc_idx) && !data[loc_idx].empty())
  1936. +                value = data[loc_idx];
  1937. +        }
  1938. +        
  1939.          int GetOrNewIndexForLocale(LocaleConstant loc);
  1940.  
  1941.          SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
  1942. diff --git a/src/game/Player.cpp b/src/game/Player.cpp
  1943. index 88f4770..1806730 100644
  1944. --- a/src/game/Player.cpp
  1945. +++ b/src/game/Player.cpp
  1946. @@ -66,6 +66,7 @@
  1947.  #include "SQLStorages.h"
  1948.  #include "Vehicle.h"
  1949.  #include "Calendar.h"
  1950. +#include "LuaEngine.h"
  1951.  
  1952.  #include <cmath>
  1953.  
  1954. @@ -569,6 +570,8 @@ Player::Player(WorldSession* session): Unit(), m_mover(this), m_camera(this), m_
  1955.  
  1956.  Player::~Player()
  1957.  {
  1958. +    Eluna::RemoveRef(this);
  1959. +    
  1960.      CleanupsBeforeDelete();
  1961.  
  1962.      // it must be unloaded already in PlayerLogout and accessed only for loggined player
  1963. @@ -1339,6 +1342,9 @@ void Player::Update(uint32 update_diff, uint32 p_time)
  1964.          if (!m_regenTimer)
  1965.              RegenerateAll();
  1966.      }
  1967. +    
  1968. +    if(!isAlive() && !HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) && getDeathState() != GHOULED)
  1969. +        SetHealth(0);
  1970.  
  1971.      if (m_deathState == JUST_DIED)
  1972.          KillPlayer();
  1973. @@ -1348,6 +1354,9 @@ void Player::Update(uint32 update_diff, uint32 p_time)
  1974.          if (update_diff >= m_nextSave)
  1975.          {
  1976.              // m_nextSave reseted in SaveToDB call
  1977. +            // Used by Eluna
  1978. +            sEluna->OnSave(this);
  1979. +            
  1980.              SaveToDB();
  1981.              DETAIL_LOG("Player '%s' (GUID: %u) saved", GetName(), GetGUIDLow());
  1982.          }
  1983. @@ -1388,7 +1397,7 @@ void Player::Update(uint32 update_diff, uint32 p_time)
  1984.      }
  1985.  
  1986.      // Not auto-free ghost from body in instances
  1987. -    if (m_deathTimer > 0  && !GetMap()->Instanceable())
  1988. +    if (m_deathTimer > 0  && !GetMap()->Instanceable() && getDeathState() != GHOULED)
  1989.      {
  1990.          if (p_time >= m_deathTimer)
  1991.          {
  1992. @@ -2455,6 +2464,9 @@ void Player::GiveXP(uint32 xp, Unit* victim)
  1993.          return;
  1994.  
  1995.      uint32 level = getLevel();
  1996. +    
  1997. +    // Used by Eluna
  1998. +    sEluna->OnGiveXP(this, xp, victim);
  1999.  
  2000.      // XP to money conversion processed in Player::RewardQuest
  2001.      if (level >= sWorld.getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL))
  2002. @@ -2502,6 +2514,8 @@ void Player::GiveXP(uint32 xp, Unit* victim)
  2003.  // Current player experience not update (must be update by caller)
  2004.  void Player::GiveLevel(uint32 level)
  2005.  {
  2006. +    uint8 oldLevel = getLevel();
  2007. +    
  2008.      if (level == getLevel())
  2009.          return;
  2010.  
  2011. @@ -2573,6 +2587,16 @@ void Player::GiveLevel(uint32 level)
  2012.          MailDraft(mailReward->mailTemplateId).SendMailTo(this, MailSender(MAIL_CREATURE, mailReward->senderEntry));
  2013.  
  2014.      GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
  2015. +
  2016. +    // Used by Eluna
  2017. +    sEluna->OnLevelChanged(this, oldLevel);
  2018. +}
  2019. +
  2020. +void Player::SetFreeTalentPoints(uint32 points)
  2021. +{
  2022. +    // Used by Eluna
  2023. +    sEluna->OnFreeTalentPointsChanged(this, points);
  2024. +    SetUInt32Value(PLAYER_CHARACTER_POINTS1, points);
  2025.  }
  2026.  
  2027.  void Player::UpdateFreeTalentPoints(bool resetIfNeed)
  2028. @@ -3712,6 +3736,9 @@ uint32 Player::resetTalentsCost() const
  2029.  
  2030.  bool Player::resetTalents(bool no_cost, bool all_specs)
  2031.  {
  2032. +    // Used by Eluna
  2033. +    sEluna->OnTalentsReset(this, no_cost);
  2034. +    
  2035.      // not need after this call
  2036.      if (HasAtLoginFlag(AT_LOGIN_RESET_TALENTS) && all_specs)
  2037.          RemoveAtLoginFlag(AT_LOGIN_RESET_TALENTS, true);
  2038. @@ -4024,6 +4051,12 @@ bool Player::HasSpell(uint32 spell) const
  2039.              !itr->second.disabled);
  2040.  }
  2041.  
  2042. +bool Player::HasTalent(uint32 spell, uint8 spec) const
  2043. +{
  2044. +    PlayerTalentMap::const_iterator itr = m_talents[spec].find(spell);
  2045. +    return (itr != m_talents[spec].end() && itr->second.state != PLAYERSPELL_REMOVED);
  2046. +}
  2047. +
  2048.  bool Player::HasActiveSpell(uint32 spell) const
  2049.  {
  2050.      PlayerSpellMap::const_iterator itr = m_spells.find(spell);
  2051. @@ -4413,7 +4446,8 @@ void Player::BuildPlayerRepop()
  2052.      GetMap()->Add(corpse);
  2053.  
  2054.      // convert player body to ghost
  2055. -    SetHealth(1);
  2056. +    if(getDeathState() != GHOULED)
  2057. +        SetHealth(1);
  2058.  
  2059.      SetWaterWalk(true);
  2060.      if (!GetSession()->isLogingOut())
  2061. @@ -4422,7 +4456,8 @@ void Player::BuildPlayerRepop()
  2062.      // BG - remove insignia related
  2063.      RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
  2064.  
  2065. -    SendCorpseReclaimDelay();
  2066. +    if(getDeathState() != GHOULED)
  2067. +        SendCorpseReclaimDelay();
  2068.  
  2069.      // to prevent cheating
  2070.      corpse->ResetGhostTime();
  2071. @@ -4476,6 +4511,8 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
  2072.      m_camera.UpdateVisibilityForOwner();
  2073.      // update visibility of player for nearby cameras
  2074.      UpdateObjectVisibility();
  2075. +    
  2076. +    sEluna->OnResurrect(this);
  2077.  
  2078.      if (!applySickness)
  2079.          return;
  2080. @@ -6344,6 +6381,9 @@ void Player::RewardReputation(Unit* pVictim, float rate)
  2081.  {
  2082.      if (!pVictim || pVictim->GetTypeId() == TYPEID_PLAYER)
  2083.          return;
  2084. +    
  2085. +    if (((Creature*)pVictim)->IsReputationGainDisabled())
  2086. +        return;
  2087.  
  2088.      // used current difficulty creature entry instead normal version (GetEntry())
  2089.      ReputationOnKillEntry const* Rep = sObjectMgr.GetReputationOnKillEntry(((Creature*)pVictim)->GetCreatureInfo()->Entry);
  2090. @@ -6814,6 +6854,9 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
  2091.          }
  2092.      }
  2093.  
  2094. +    // Used by Eluna
  2095. +    sEluna->OnUpdateZone(this, newZone, newArea);
  2096. +    
  2097.      m_zoneUpdateId    = newZone;
  2098.      m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
  2099.  
  2100. @@ -6945,6 +6988,9 @@ void Player::DuelComplete(DuelCompleteType type)
  2101.          data << GetName();
  2102.          SendMessageToSet(&data, true);
  2103.      }
  2104. +    
  2105. +    // Used by Eluna
  2106. +    sEluna->OnDuelEnd(duel->opponent, this, type);
  2107.  
  2108.      if (type == DUEL_WON)
  2109.      {
  2110. @@ -11131,6 +11177,9 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
  2111.          pItem2->SetState(ITEM_CHANGED, this);
  2112.  
  2113.          ApplyEquipCooldown(pItem2);
  2114. +        
  2115. +        // Used by Eluna
  2116. +        sEluna->OnEquip(this, pItem2, bag, slot);
  2117.  
  2118.          return pItem2;
  2119.      }
  2120. @@ -11142,6 +11191,9 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
  2121.      GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry());
  2122.      GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, slot + 1);
  2123.  
  2124. +    // Used by Eluna
  2125. +    sEluna->OnEquip(this, pItem, bag, slot);
  2126. +    
  2127.      return pItem;
  2128.  }
  2129.  
  2130. @@ -11369,6 +11421,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
  2131.              ApplyItemOnStoreSpell(pItem, false);
  2132.  
  2133.          ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
  2134. +        sEluna->OnRemove(this, pItem);
  2135.  
  2136.          if (bag == INVENTORY_SLOT_BAG_0)
  2137.          {
  2138. @@ -14982,8 +15035,10 @@ void Player::SendQuestCompleteEvent(uint32 quest_id)
  2139.      }
  2140.  }
  2141.  
  2142. -void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* /*questGiver*/)
  2143. +void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* questGiver)
  2144.  {
  2145. +    Player* pPlayer = m_session->GetPlayer();
  2146. +    
  2147.      uint32 questid = pQuest->GetQuestId();
  2148.      DEBUG_LOG("WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
  2149.      WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4 + 4 + 4 + 4 + 4));
  2150. @@ -15004,6 +15059,13 @@ void Player::SendQuestReward(Quest const* pQuest, uint32 XP, Object* /*questGive
  2151.      data << uint32(pQuest->GetBonusTalents());              // bonus talents
  2152.      data << uint32(0);                                      // arena points
  2153.      GetSession()->SendPacket(&data);
  2154. +    
  2155. +    // Used by Eluna
  2156. +    if (Creature* pCreature = questGiver->ToCreature())
  2157. +        sEluna->OnQuestComplete(pPlayer, pCreature, pQuest);
  2158. +    
  2159. +    if (GameObject* pGameObject = questGiver->ToGameObject())
  2160. +        sEluna->OnQuestComplete(pPlayer, pGameObject, pQuest);
  2161.  }
  2162.  
  2163.  void Player::SendQuestFailed(uint32 quest_id, InventoryResult reason)
  2164. @@ -16849,6 +16911,9 @@ InstancePlayerBind* Player::BindToInstance(DungeonPersistentState* state, bool p
  2165.          if (!load)
  2166.              DEBUG_LOG("Player::BindToInstance: %s(%d) is now bound to map %d, instance %d, difficulty %d",
  2167.                        GetName(), GetGUIDLow(), state->GetMapId(), state->GetInstanceId(), state->GetDifficulty());
  2168. +        
  2169. +        // Used by Eluna
  2170. +        sEluna->OnBindToInstance(this, state->GetDifficulty(), state->GetMapId(), permanent);
  2171.          return &bind;
  2172.      }
  2173.      else
  2174. @@ -18174,6 +18239,9 @@ void Player::UpdateDuelFlag(time_t currTime)
  2175.  {
  2176.      if (!duel || duel->startTimer == 0 || currTime < duel->startTimer + 3)
  2177.          return;
  2178. +    
  2179. +    // Used by Eluna
  2180. +    sEluna->OnDuelStart(this, duel->opponent);
  2181.  
  2182.      SetUInt32Value(PLAYER_DUEL_TEAM, 1);
  2183.      duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 2);
  2184. @@ -22747,6 +22815,21 @@ void Player::UpdateSpecCount(uint8 count)
  2185.      SendTalentsInfoData(false);
  2186.  }
  2187.  
  2188. +void Player::ModifyMoney(int32 d)
  2189. +{
  2190. +    // Used by Eluna
  2191. +    sEluna->OnMoneyChanged(this, d);
  2192. +    
  2193. +    if (d < 0)
  2194. +        SetMoney(GetMoney() > uint32(-d) ? GetMoney() + d : 0);
  2195. +    else
  2196. +        SetMoney(GetMoney() < uint32(MAX_MONEY_AMOUNT - d) ? GetMoney() + d : MAX_MONEY_AMOUNT);
  2197. +    
  2198. +    // "At Gold Limit"
  2199. +    if (GetMoney() >= MAX_MONEY_AMOUNT)
  2200. +        SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL);
  2201. +}
  2202. +
  2203.  void Player::RemoveAtLoginFlag(AtLoginFlags f, bool in_db_also /*= false*/)
  2204.  {
  2205.      m_atLoginFlags &= ~f;
  2206. diff --git a/src/game/Player.h b/src/game/Player.h
  2207. index 44b127b..200b40f 100644
  2208. --- a/src/game/Player.h
  2209. +++ b/src/game/Player.h
  2210. @@ -1035,6 +1035,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  2211.  
  2212.          bool IsInWater() const override { return m_isInWater; }
  2213.          bool IsUnderWater() const override;
  2214. +        bool IsFalling() { return GetPositionZ() < m_lastFallZ; }
  2215.  
  2216.          void SendInitialPacketsBeforeAddToMap();
  2217.          void SendInitialPacketsAfterAddToMap();
  2218. @@ -1463,17 +1464,8 @@ class MANGOS_DLL_SPEC Player : public Unit
  2219.          void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;}
  2220.  
  2221.          uint32 GetMoney() const { return GetUInt32Value(PLAYER_FIELD_COINAGE); }
  2222. -        void ModifyMoney(int32 d)
  2223. -        {
  2224. -            if (d < 0)
  2225. -                SetMoney(GetMoney() > uint32(-d) ? GetMoney() + d : 0);
  2226. -            else
  2227. -                SetMoney(GetMoney() < uint32(MAX_MONEY_AMOUNT - d) ? GetMoney() + d : MAX_MONEY_AMOUNT);
  2228. -
  2229. -            // "At Gold Limit"
  2230. -            if (GetMoney() >= MAX_MONEY_AMOUNT)
  2231. -                SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL);
  2232. -        }
  2233. +        void ModifyMoney(int32 d);
  2234. +        
  2235.          void SetMoney(uint32 value)
  2236.          {
  2237.              SetUInt32Value(PLAYER_FIELD_COINAGE, value);
  2238. @@ -1561,7 +1553,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  2239.          void learnSpellHighRank(uint32 spellid);
  2240.  
  2241.          uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
  2242. -        void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1, points); }
  2243. +        void SetFreeTalentPoints(uint32 points);
  2244.          void UpdateFreeTalentPoints(bool resetIfNeed = true);
  2245.          bool resetTalents(bool no_cost = false, bool all_specs = false);
  2246.          uint32 resetTalentsCost() const;
  2247. @@ -1571,7 +1563,8 @@ class MANGOS_DLL_SPEC Player : public Unit
  2248.          void SendTalentsInfoData(bool pet);
  2249.          void LearnTalent(uint32 talentId, uint32 talentRank);
  2250.          void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank);
  2251. -
  2252. +        bool HasTalent(uint32 spell_id, uint8 spec) const;
  2253. +        
  2254.          uint32 CalculateTalentsPoints() const;
  2255.  
  2256.          // Dual Spec
  2257. @@ -1893,6 +1886,7 @@ class MANGOS_DLL_SPEC Player : public Unit
  2258.  
  2259.          static Team TeamForRace(uint8 race);
  2260.          Team GetTeam() const { return m_team; }
  2261. +        TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
  2262.          static uint32 getFactionForRace(uint8 race);
  2263.          void setFactionForRace(uint8 race);
  2264.  
  2265. diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
  2266. index fcbc93d..19dba86 100644
  2267. --- a/src/game/QuestHandler.cpp
  2268. +++ b/src/game/QuestHandler.cpp
  2269. @@ -29,6 +29,7 @@
  2270.  #include "ObjectAccessor.h"
  2271.  #include "ScriptMgr.h"
  2272.  #include "Group.h"
  2273. +#include "LuaEngine.h"
  2274.  
  2275.  void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recv_data)
  2276.  {
  2277. @@ -344,6 +345,9 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recv_data)
  2278.              }
  2279.  
  2280.              _player->SetQuestStatus(quest, QUEST_STATUS_NONE);
  2281. +            
  2282. +            // Used by Eluna
  2283. +            sEluna->OnQuestAbandon(_player, quest);
  2284.          }
  2285.  
  2286.          _player->SetQuestSlot(slot, 0);
  2287. diff --git a/src/game/ReputationMgr.cpp b/src/game/ReputationMgr.cpp
  2288. index db07c2f..c194834 100644
  2289. --- a/src/game/ReputationMgr.cpp
  2290. +++ b/src/game/ReputationMgr.cpp
  2291. @@ -21,6 +21,7 @@
  2292.  #include "Player.h"
  2293.  #include "WorldPacket.h"
  2294.  #include "ObjectMgr.h"
  2295. +#include "LuaEngine.h"
  2296.  
  2297.  const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
  2298.  
  2299. @@ -233,6 +234,9 @@ void ReputationMgr::Initialize()
  2300.  
  2301.  void ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental)
  2302.  {
  2303. +    // Used by Eluna
  2304. +    sEluna->OnReputationChange(m_player, factionEntry->ID, standing, incremental);
  2305. +    
  2306.      bool anyRankIncreased = false;
  2307.  
  2308.      // if spillover definition exists in DB, override DBC
  2309. diff --git a/src/game/ScriptMgr.cpp b/src/game/ScriptMgr.cpp
  2310. index 6bb2706..fb210d4 100644
  2311. --- a/src/game/ScriptMgr.cpp
  2312. +++ b/src/game/ScriptMgr.cpp
  2313. @@ -31,6 +31,7 @@
  2314.  #include "BattleGround/BattleGround.h"
  2315.  #include "OutdoorPvP/OutdoorPvP.h"
  2316.  #include "WaypointMovementGenerator.h"
  2317. +#include "LuaEngine.h"
  2318.  
  2319.  #include "revision_nr.h"
  2320.  
  2321. @@ -73,6 +74,7 @@ ScriptMgr::ScriptMgr() :
  2322.      m_pOnGOUse(NULL),
  2323.      m_pOnItemUse(NULL),
  2324.      m_pOnAreaTrigger(NULL),
  2325. +    m_pOnNpcSpellClick(NULL),
  2326.      m_pOnProcessEvent(NULL),
  2327.      m_pOnEffectDummyCreature(NULL),
  2328.      m_pOnEffectDummyGO(NULL),
  2329. @@ -1988,6 +1990,10 @@ char const* ScriptMgr::GetScriptLibraryVersion() const
  2330.  
  2331.  CreatureAI* ScriptMgr::GetCreatureAI(Creature* pCreature)
  2332.  {
  2333. +    // Used by Eluna
  2334. +    if (CreatureAI* luaAI = sEluna->GetAI(pCreature))
  2335. +        return luaAI;
  2336. +    
  2337.      if (!m_pGetCreatureAI)
  2338.          return NULL;
  2339.  
  2340. @@ -2004,17 +2010,38 @@ InstanceData* ScriptMgr::CreateInstanceData(Map* pMap)
  2341.  
  2342.  bool ScriptMgr::OnGossipHello(Player* pPlayer, Creature* pCreature)
  2343.  {
  2344. +    // Used by Eluna
  2345. +    if (sEluna->OnGossipHello(pPlayer, pCreature))
  2346. +        return true;
  2347. +    
  2348.      return m_pOnGossipHello != NULL && m_pOnGossipHello(pPlayer, pCreature);
  2349.  }
  2350.  
  2351.  bool ScriptMgr::OnGossipHello(Player* pPlayer, GameObject* pGameObject)
  2352.  {
  2353. +    // Used by Eluna
  2354. +    if (sEluna->OnGossipHello(pPlayer, pGameObject))
  2355. +        return true;
  2356. +    
  2357.      return m_pOnGOGossipHello != NULL && m_pOnGOGossipHello(pPlayer, pGameObject);
  2358.  }
  2359.  
  2360.  bool ScriptMgr::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code)
  2361.  {
  2362.      if (code)
  2363. +    {
  2364. +        // Used by Eluna
  2365. +        if (sEluna->OnGossipSelectCode(pPlayer, pCreature, sender, action, code))
  2366. +            return true;
  2367. +    }
  2368. +    else
  2369. +    {
  2370. +        // Used by Eluna
  2371. +        if (sEluna->OnGossipSelect(pPlayer, pCreature, sender, action))
  2372. +            return true;
  2373. +    }
  2374. +    
  2375. +    if (code)
  2376.          return m_pOnGossipSelectWithCode != NULL && m_pOnGossipSelectWithCode(pPlayer, pCreature, sender, action, code);
  2377.      else
  2378.          return m_pOnGossipSelect != NULL && m_pOnGossipSelect(pPlayer, pCreature, sender, action);
  2379. @@ -2023,6 +2050,15 @@ bool ScriptMgr::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 send
  2380.  bool ScriptMgr::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code)
  2381.  {
  2382.      if (code)
  2383. +    {
  2384. +        if (sEluna->OnGossipSelectCode(pPlayer, pGameObject, sender, action, code))
  2385. +            return true;
  2386. +    }
  2387. +    else
  2388. +        if (sEluna->OnGossipSelect(pPlayer, pGameObject, sender, action))
  2389. +            return true;
  2390. +        
  2391. +    if (code)
  2392.          return m_pOnGOGossipSelectWithCode != NULL && m_pOnGOGossipSelectWithCode(pPlayer, pGameObject, sender, action, code);
  2393.      else
  2394.          return m_pOnGOGossipSelect != NULL && m_pOnGOGossipSelect(pPlayer, pGameObject, sender, action);
  2395. @@ -2030,31 +2066,55 @@ bool ScriptMgr::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32
  2396.  
  2397.  bool ScriptMgr::OnQuestAccept(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
  2398.  {
  2399. +    // used by eluna
  2400. +    if (sEluna->OnQuestAccept(pPlayer, pCreature, pQuest))
  2401. +        return true;
  2402. +    
  2403.      return m_pOnQuestAccept != NULL && m_pOnQuestAccept(pPlayer, pCreature, pQuest);
  2404.  }
  2405.  
  2406.  bool ScriptMgr::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest)
  2407.  {
  2408. +    // used by eluna
  2409. +    if (sEluna->OnQuestAccept(pPlayer, pGameObject, pQuest))
  2410. +        return true;
  2411. +    
  2412.      return m_pOnGOQuestAccept != NULL && m_pOnGOQuestAccept(pPlayer, pGameObject, pQuest);
  2413.  }
  2414.  
  2415.  bool ScriptMgr::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest)
  2416.  {
  2417. +    // used by eluna
  2418. +    if (sEluna->OnQuestAccept(pPlayer, pItem, pQuest))
  2419. +        return true;
  2420. +    
  2421.      return m_pOnItemQuestAccept != NULL && m_pOnItemQuestAccept(pPlayer, pItem, pQuest);
  2422.  }
  2423.  
  2424.  bool ScriptMgr::OnQuestRewarded(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
  2425.  {
  2426. +    // used by eluna
  2427. +    if (sEluna->OnQuestReward(pPlayer, pCreature, pQuest))
  2428. +        return true;
  2429. +    
  2430.      return m_pOnQuestRewarded != NULL && m_pOnQuestRewarded(pPlayer, pCreature, pQuest);
  2431.  }
  2432.  
  2433.  bool ScriptMgr::OnQuestRewarded(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest)
  2434.  {
  2435. +    // used by eluna
  2436. +    if (sEluna->OnQuestReward(pPlayer, pGameObject, pQuest))
  2437. +        return true;
  2438. +    
  2439.      return m_pOnGOQuestRewarded != NULL && m_pOnGOQuestRewarded(pPlayer, pGameObject, pQuest);
  2440.  }
  2441.  
  2442.  uint32 ScriptMgr::GetDialogStatus(Player* pPlayer, Creature* pCreature)
  2443.  {
  2444. +    // used by eluna
  2445. +    if (uint32 dialogId = sEluna->GetDialogStatus(pPlayer, pCreature))
  2446. +        return dialogId;
  2447. +    
  2448.      if (!m_pGetNPCDialogStatus)
  2449.          return DIALOG_STATUS_UNDEFINED;
  2450.  
  2451. @@ -2063,6 +2123,10 @@ uint32 ScriptMgr::GetDialogStatus(Player* pPlayer, Creature* pCreature)
  2452.  
  2453.  uint32 ScriptMgr::GetDialogStatus(Player* pPlayer, GameObject* pGameObject)
  2454.  {
  2455. +    // used by eluna
  2456. +    if (uint32 dialogId = sEluna->GetDialogStatus(pPlayer, pGameObject))
  2457. +        return dialogId;
  2458. +    
  2459.      if (!m_pGetGODialogStatus)
  2460.          return DIALOG_STATUS_UNDEFINED;
  2461.  
  2462. @@ -2076,14 +2140,27 @@ bool ScriptMgr::OnGameObjectUse(Player* pPlayer, GameObject* pGameObject)
  2463.  
  2464.  bool ScriptMgr::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
  2465.  {
  2466. +    // used by eluna
  2467. +     if(sEluna->OnUse(pPlayer, pItem, targets)) // says if (!sEluna... on cmangos repo..)
  2468. +         return true;
  2469. +    
  2470.      return m_pOnItemUse != NULL && m_pOnItemUse(pPlayer, pItem, targets);
  2471.  }
  2472.  
  2473.  bool ScriptMgr::OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* atEntry)
  2474.  {
  2475. +    // used by eluna
  2476. +    if(sEluna->OnAreaTrigger(pPlayer, atEntry))
  2477. +        return true;
  2478. +    
  2479.      return m_pOnAreaTrigger != NULL && m_pOnAreaTrigger(pPlayer, atEntry);
  2480.  }
  2481.  
  2482. +bool ScriptMgr::OnNpcSpellClick(Player* pPlayer, Creature* pClickedCreature, uint32 spellId)
  2483. +{
  2484. +    return m_pOnNpcSpellClick != NULL && m_pOnNpcSpellClick(pPlayer, pClickedCreature, spellId);
  2485. +}
  2486. +
  2487.  bool ScriptMgr::OnProcessEvent(uint32 eventId, Object* pSource, Object* pTarget, bool isStart)
  2488.  {
  2489.      return m_pOnProcessEvent != NULL && m_pOnProcessEvent(eventId, pSource, pTarget, isStart);
  2490. @@ -2091,16 +2168,28 @@ bool ScriptMgr::OnProcessEvent(uint32 eventId, Object* pSource, Object* pTarget,
  2491.  
  2492.  bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid)
  2493.  {
  2494. +    // used by eluna
  2495. +    if(sEluna->OnDummyEffect(pCaster, spellId, effIndex, pTarget))
  2496. +        return true;
  2497. +    
  2498.      return m_pOnEffectDummyCreature != NULL && m_pOnEffectDummyCreature(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
  2499.  }
  2500.  
  2501.  bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget, ObjectGuid originalCasterGuid)
  2502.  {
  2503. +    // used by eluna
  2504. +    if (sEluna->OnDummyEffect(pCaster, spellId, effIndex, pTarget))
  2505. +        return true;
  2506. +    
  2507.      return m_pOnEffectDummyGO != NULL && m_pOnEffectDummyGO(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
  2508.  }
  2509.  
  2510.  bool ScriptMgr::OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Item* pTarget, ObjectGuid originalCasterGuid)
  2511.  {
  2512. +    // used by eluna
  2513. +    if(sEluna->OnDummyEffect(pCaster, spellId, effIndex, pTarget))
  2514. +        return true;
  2515. +    
  2516.      return m_pOnEffectDummyItem != NULL && m_pOnEffectDummyItem(pCaster, spellId, effIndex, pTarget, originalCasterGuid);
  2517.  }
  2518.  
  2519. @@ -2164,6 +2253,7 @@ ScriptLoadResult ScriptMgr::LoadScriptLibrary(const char* libName)
  2520.      GET_SCRIPT_HOOK_PTR(m_pOnGOUse,                    "GOUse");
  2521.      GET_SCRIPT_HOOK_PTR(m_pOnItemUse,                  "ItemUse");
  2522.      GET_SCRIPT_HOOK_PTR(m_pOnAreaTrigger,              "AreaTrigger");
  2523. +    GET_SCRIPT_HOOK_PTR(m_pOnNpcSpellClick,            "NpcSpellClick");
  2524.      GET_SCRIPT_HOOK_PTR(m_pOnProcessEvent,             "ProcessEvent");
  2525.      GET_SCRIPT_HOOK_PTR(m_pOnEffectDummyCreature,      "EffectDummyCreature");
  2526.      GET_SCRIPT_HOOK_PTR(m_pOnEffectDummyGO,            "EffectDummyGameObject");
  2527. @@ -2218,6 +2308,7 @@ void ScriptMgr::UnloadScriptLibrary()
  2528.      m_pOnGOUse                  = NULL;
  2529.      m_pOnItemUse                = NULL;
  2530.      m_pOnAreaTrigger            = NULL;
  2531. +    m_pOnNpcSpellClick          = NULL;
  2532.      m_pOnProcessEvent           = NULL;
  2533.      m_pOnEffectDummyCreature    = NULL;
  2534.      m_pOnEffectDummyGO          = NULL;
  2535. diff --git a/src/game/ScriptMgr.h b/src/game/ScriptMgr.h
  2536. index d3abdaf..715e29c 100644
  2537. --- a/src/game/ScriptMgr.h
  2538. +++ b/src/game/ScriptMgr.h
  2539. @@ -509,6 +509,7 @@ class ScriptMgr
  2540.          bool OnGameObjectUse(Player* pPlayer, GameObject* pGameObject);
  2541.          bool OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets);
  2542.          bool OnAreaTrigger(Player* pPlayer, AreaTriggerEntry const* atEntry);
  2543. +        bool OnNpcSpellClick(Player* pPlayer, Creature* pClickedCreature, uint32 spellId);
  2544.          bool OnProcessEvent(uint32 eventId, Object* pSource, Object* pTarget, bool isStart);
  2545.          bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, Creature* pTarget, ObjectGuid originalCasterGuid);
  2546.          bool OnEffectDummy(Unit* pCaster, uint32 spellId, SpellEffectIndex effIndex, GameObject* pTarget, ObjectGuid originalCasterGuid);
  2547. @@ -563,6 +564,7 @@ class ScriptMgr
  2548.          bool (MANGOS_IMPORT* m_pOnGOUse)(Player*, GameObject*);
  2549.          bool (MANGOS_IMPORT* m_pOnItemUse)(Player*, Item*, SpellCastTargets const&);
  2550.          bool (MANGOS_IMPORT* m_pOnAreaTrigger)(Player*, AreaTriggerEntry const*);
  2551. +        bool (MANGOS_IMPORT* m_pOnNpcSpellClick)(Player*, Creature*, uint32);
  2552.          bool (MANGOS_IMPORT* m_pOnProcessEvent)(uint32, Object*, Object*, bool);
  2553.          bool (MANGOS_IMPORT* m_pOnEffectDummyCreature)(Unit*, uint32, SpellEffectIndex, Creature*, ObjectGuid);
  2554.          bool (MANGOS_IMPORT* m_pOnEffectDummyGO)(Unit*, uint32, SpellEffectIndex, GameObject*, ObjectGuid);
  2555. diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
  2556. index 74652e7..50d902a 100644
  2557. --- a/src/game/SharedDefines.h
  2558. +++ b/src/game/SharedDefines.h
  2559. @@ -22,6 +22,9 @@
  2560.  #include "Platform/Define.h"
  2561.  #include <cassert>
  2562.  
  2563. +#define MANGOS
  2564. +#define WOTLK
  2565. +
  2566.  enum Gender
  2567.  {
  2568.      GENDER_MALE                        = 0,
  2569. @@ -155,6 +158,7 @@ enum Powers
  2570.      POWER_HAPPINESS                     = 4,
  2571.      POWER_RUNE                          = 5,
  2572.      POWER_RUNIC_POWER                   = 6,
  2573. +    POWER_ALL                           = 127,
  2574.      POWER_HEALTH                        = 0xFFFFFFFE    // (-2 as signed value)
  2575.  };
  2576.  
  2577. @@ -604,6 +608,13 @@ enum Language
  2578.  
  2579.  #define LANGUAGES_COUNT   19
  2580.  
  2581. +enum TeamId
  2582. +{
  2583. +    TEAM_ALLIANCE = 0,
  2584. +    TEAM_HORDE,
  2585. +    TEAM_NEUTRAL
  2586. +};
  2587. +
  2588.  // In fact !=0 values is alliance/horde root faction ids
  2589.  enum Team
  2590.  {
  2591. @@ -757,7 +768,7 @@ enum SpellEffects
  2592.      SPELL_EFFECT_LEAP_BACK                 = 138,
  2593.      SPELL_EFFECT_CLEAR_QUEST               = 139,
  2594.      SPELL_EFFECT_FORCE_CAST                = 140,
  2595. -    SPELL_EFFECT_141                       = 141,
  2596. +    SPELL_EFFECT_FORCE_CAST_WITH_VALUE     = 141,
  2597.      SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE  = 142,
  2598.      SPELL_EFFECT_APPLY_AREA_AURA_OWNER     = 143,
  2599.      SPELL_EFFECT_KNOCKBACK_FROM_POSITION   = 144,
  2600. diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
  2601. index a1603f6..1f5a756 100644
  2602. --- a/src/game/Spell.cpp
  2603. +++ b/src/game/Spell.cpp
  2604. @@ -47,6 +47,7 @@
  2605.  #include "Vehicle.h"
  2606.  #include "TemporarySummon.h"
  2607.  #include "SQLStorages.h"
  2608. +#include "LuaEngine.h"
  2609.  
  2610.  extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
  2611.  
  2612. @@ -419,6 +420,7 @@ Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid or
  2613.  
  2614.  Spell::~Spell()
  2615.  {
  2616. +    Eluna::RemoveRef(this);
  2617.  }
  2618.  
  2619.  template<typename T>
  2620. @@ -3326,6 +3328,9 @@ void Spell::cast(bool skipCheck)
  2621.              ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry());
  2622.  
  2623.          ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
  2624. +    
  2625. +        // used by eluna
  2626. +        sEluna->OnSpellCast(m_caster->ToPlayer(), this, skipCheck);
  2627.      }
  2628.  
  2629.      FillTargetMap();
  2630. @@ -7677,6 +7682,7 @@ void Spell::GetSpellRangeAndRadius(SpellEffectIndex effIndex, float& radius, uin
  2631.                  case 44869:                                 // Spectral Blast (SWP, Kalecgos)
  2632.                  case 45391:                                 // Summon Demonic Vapor (SWP, Felmyst)
  2633.                  case 45785:                                 // Sinister Reflection Clone (SWP, Kil'jaeden)
  2634. +                case 45863:                                 // Cosmetic - Incinerate to Random Target (Borean Tundra)
  2635.                  case 45892:                                 // Sinister Reflection (SWP, Kil'jaeden)
  2636.                  case 45976:                                 // Open Portal (SWP, M'uru)
  2637.                  case 46372:                                 // Ice Spear Target Picker (Slave Pens, Ahune)
  2638. diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
  2639. index e24cb1b..ffa57e3 100644
  2640. --- a/src/game/SpellAuraDefines.h
  2641. +++ b/src/game/SpellAuraDefines.h
  2642. @@ -385,7 +385,7 @@ enum AuraType
  2643.      SPELL_AURA_MOD_EXPERTISE = 240,
  2644.      SPELL_AURA_FORCE_MOVE_FORWARD = 241,
  2645.      SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING = 242,
  2646. -    SPELL_AURA_243 = 243,
  2647. +    SPELL_AURA_FACTION_OVERRIDE = 243,
  2648.      SPELL_AURA_COMPREHEND_LANGUAGE = 244,
  2649.      SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
  2650.      SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL = 246,
  2651. @@ -421,7 +421,7 @@ enum AuraType
  2652.      SPELL_AURA_276 = 276,                                   // Only "Test Mod Damage % Mechanic" spell, possible mod damage done
  2653.      SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
  2654.      SPELL_AURA_MOD_DISARM_RANGED = 278,
  2655. -    SPELL_AURA_279 = 279,
  2656. +    SPELL_AURA_MIRROR_NAME = 279,
  2657.      SPELL_AURA_MOD_TARGET_ARMOR_PCT = 280,
  2658.      SPELL_AURA_MOD_HONOR_GAIN = 281,
  2659.      SPELL_AURA_MOD_BASE_HEALTH_PCT = 282,
  2660. diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
  2661. index 98d99c7..a0d43c5 100644
  2662. --- a/src/game/SpellAuras.cpp
  2663. +++ b/src/game/SpellAuras.cpp
  2664. @@ -48,6 +48,7 @@
  2665.  #include "CellImpl.h"
  2666.  #include "Language.h"
  2667.  #include "MapManager.h"
  2668. +#include "LuaEngine.h"
  2669.  
  2670.  #define NULL_AURA_SLOT 0xFF
  2671.  
  2672. @@ -300,7 +301,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] =
  2673.      &Aura::HandleAuraModExpertise,                          //240 SPELL_AURA_MOD_EXPERTISE
  2674.      &Aura::HandleForceMoveForward,                          //241 Forces the caster to move forward
  2675.      &Aura::HandleUnused,                                    //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING (only 2 test spels in 3.2.2a)
  2676. -    &Aura::HandleNULL,                                      //243 faction reaction override spells
  2677. +    &Aura::HandleFactionOverride,                           //243 SPELL_AURA_FACTION_OVERRIDE
  2678.      &Aura::HandleComprehendLanguage,                        //244 SPELL_AURA_COMPREHEND_LANGUAGE
  2679.      &Aura::HandleNoImmediateEffect,                         //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS     implemented in Unit::CalculateAuraDuration
  2680.      &Aura::HandleNoImmediateEffect,                         //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL implemented in Unit::CalculateAuraDuration
  2681. @@ -336,7 +337,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] =
  2682.      &Aura::HandleNULL,                                      //276 mod damage % mechanic?
  2683.      &Aura::HandleNoImmediateEffect,                         //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select
  2684.      &Aura::HandleAuraModDisarm,                             //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
  2685. -    &Aura::HandleNULL,                                      //279 visual effects? 58836 and 57507
  2686. +    &Aura::HandleMirrorName,                                //279 SPELL_AURA_MIRROR_NAME target receives the casters name
  2687.      &Aura::HandleModTargetArmorPct,                         //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
  2688.      &Aura::HandleNoImmediateEffect,                         //281 SPELL_AURA_MOD_HONOR_GAIN             implemented in Player::RewardHonor
  2689.      &Aura::HandleAuraIncreaseBaseHealthPercent,             //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
  2690. @@ -444,6 +445,7 @@ Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBas
  2691.  
  2692.  Aura::~Aura()
  2693.  {
  2694. +    Eluna::RemoveRef(this);
  2695.  }
  2696.  
  2697.  AreaAura::AreaAura(SpellEntry const* spellproto, SpellEffectIndex eff, int32* currentBasePoints, SpellAuraHolder* holder, Unit* target,
  2698. @@ -1106,8 +1108,9 @@ void Aura::TriggerSpell()
  2699.  //                    // Polymorphic Ray
  2700.  //                    case 6965: break;
  2701.                      case 9712:                              // Thaumaturgy Channel
  2702. -                        trigger_spell_id = 21029;
  2703. -                        break;
  2704. +                        if (Unit* caster = GetCaster())
  2705. +                            caster->CastSpell(caster, 21029, true);
  2706. +                        return;
  2707.  //                    // Egan's Blaster
  2708.  //                    case 17368: break;
  2709.  //                    // Haunted
  2710. @@ -8373,9 +8376,19 @@ void Aura::PeriodicDummyTick()
  2711.          }
  2712.          case SPELLFAMILY_MAGE:
  2713.          {
  2714. -            // Mirror Image
  2715. -//            if (spell->Id == 55342)
  2716. -//                return;
  2717. +            switch (spell->Id)
  2718. +            {
  2719. +                case 55342:                       // Mirror Image
  2720. +                {
  2721. +                    if (GetAuraTicks() != 1)
  2722. +                        return;
  2723. +                    if (Unit* pCaster = GetCaster())
  2724. +                        pCaster->CastSpell(pCaster, spell->EffectTriggerSpell[GetEffIndex()], true, NULL, this);
  2725. +                    return;
  2726. +                }
  2727. +                default:
  2728. +                    break;
  2729. +            }
  2730.              break;
  2731.          }
  2732.          case SPELLFAMILY_DRUID:
  2733. @@ -8737,6 +8750,29 @@ void Aura::HandleAuraMirrorImage(bool apply, bool Real)
  2734.      }
  2735.  }
  2736.  
  2737. +void Aura::HandleMirrorName(bool apply, bool Real)
  2738. +{
  2739. +    if (!Real)
  2740. +        return;
  2741. +    
  2742. +    Unit* caster = GetCaster();
  2743. +    Unit* target = GetTarget();
  2744. +    
  2745. +    if (!target || !caster || target->GetTypeId() != TYPEID_UNIT)
  2746. +        return;
  2747. +    
  2748. +    if (apply)
  2749. +        target->SetName(caster->GetName());
  2750. +    else
  2751. +    {
  2752. +        CreatureInfo const* cinfo = ((Creature*)target)->GetCreatureInfo();
  2753. +        if (!cinfo)
  2754. +            return;
  2755. +        
  2756. +        target->SetName(cinfo->Name);
  2757. +    }
  2758. +}
  2759. +
  2760.  void Aura::HandleAuraConvertRune(bool apply, bool Real)
  2761.  {
  2762.      if (!Real)
  2763. @@ -8875,6 +8911,21 @@ void Aura::HandleAuraSetVehicleId(bool apply, bool Real)
  2764.      GetTarget()->SetVehicleId(apply ? GetMiscValue() : 0, 0);
  2765.  }
  2766.  
  2767. +void Aura::HandleFactionOverride(bool apply, bool Real)
  2768. +{
  2769. +    if (!Real)
  2770. +        return;
  2771. +    
  2772. +    Unit* target = GetTarget();
  2773. +    if (!target || !sFactionTemplateStore.LookupEntry(GetMiscValue()))
  2774. +        return;
  2775. +    
  2776. +    if (apply)
  2777. +        target->setFaction(GetMiscValue());
  2778. +    else
  2779. +        target->RestoreOriginalFaction();
  2780. +}
  2781. +
  2782.  bool Aura::IsLastAuraOnHolder()
  2783.  {
  2784.      for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
  2785. @@ -9891,7 +9942,48 @@ void SpellAuraHolder::HandleSpellSpecificBoosts(bool apply)
  2786.              switch (GetId())
  2787.              {
  2788.                  case 49039: spellId1 = 50397; break;        // Lichborne
  2789. -
  2790. +                case 46619:                                 // Raise ally
  2791. +                {
  2792. +                    if (!m_target || m_target->GetTypeId() != TYPEID_PLAYER)
  2793. +                        return;
  2794. +                    Player* m_player = (Player*)m_target;
  2795. +                    if (apply)
  2796. +                    {
  2797. +                       // turn player into ghoul
  2798. +                        m_player->SetDeathState(GHOULED);
  2799. +                        m_player->SetHealth(1);
  2800. +                        m_player->SetRoot(true);
  2801. +                    }
  2802. +                    else
  2803. +                    {
  2804. +                        m_player->SetRoot(false);
  2805. +                        m_player->SetHealth(0);
  2806. +                        m_player->SetDeathState(JUST_DIED);
  2807. +                    }
  2808. +                    break;
  2809. +                }
  2810. +                case 48979:                                 // Butchery, rank 1
  2811. +                case 49483:                                 // Butchery, rank 2
  2812. +                {
  2813. +                    if(GetId() == 48979) // rank 1
  2814. +                    {
  2815. +                        if (!m_target || m_target->getDeathState() != JUST_DIED)
  2816. +                            return;
  2817. +                        // give 10 runic power and
  2818. +                        // cast spell for 2 runic power per 5 sec in combat
  2819. +                    
  2820. +                        m_target->ModifyPower(POWER_RUNIC_POWER, (int32)10);
  2821. +                    }
  2822. +                    else if(GetId() == 49483) // rank 2
  2823. +                    {
  2824. +                        if (!m_target || m_target->getDeathState() != JUST_DIED)
  2825. +                            return;
  2826. +                        // give 20 runic power and extra 2 runic power per 5 sec in combat
  2827. +                    
  2828. +                        m_target->ModifyPower(POWER_RUNIC_POWER, (int32)20);
  2829. +                    }
  2830. +                    break;
  2831. +                }
  2832.                  case 48263:                                 // Frost Presence
  2833.                  case 48265:                                 // Unholy Presence
  2834.                  case 48266:                                 // Blood Presence
  2835. diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
  2836. index 653c05b..fd2f115 100644
  2837. --- a/src/game/SpellAuras.h
  2838. +++ b/src/game/SpellAuras.h
  2839. @@ -409,6 +409,8 @@ class MANGOS_DLL_SPEC Aura
  2840.          void HandleAuraAddMechanicAbilities(bool apply, bool Real);
  2841.          void HandleAuraStopNaturalManaRegen(bool apply, bool Real);
  2842.          void HandleAuraSetVehicleId(bool apply, bool Real);
  2843. +        void HandleMirrorName(bool apply, bool Real);
  2844. +        void HandleFactionOverride(bool apply, bool Real);
  2845.  
  2846.          virtual ~Aura();
  2847.  
  2848. diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
  2849. index d55e749..50edb4e 100644
  2850. --- a/src/game/SpellEffects.cpp
  2851. +++ b/src/game/SpellEffects.cpp
  2852. @@ -57,6 +57,7 @@
  2853.  #include "GridNotifiers.h"
  2854.  #include "GridNotifiersImpl.h"
  2855.  #include "CellImpl.h"
  2856. +#include "LuaEngine.h"
  2857.  
  2858.  pEffect SpellEffects[TOTAL_SPELL_EFFECTS] =
  2859.  {
  2860. @@ -201,7 +202,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS] =
  2861.      &Spell::EffectLeapBack,                                 //138 SPELL_EFFECT_LEAP_BACK                Leap back
  2862.      &Spell::EffectClearQuest,                               //139 SPELL_EFFECT_CLEAR_QUEST              (misc - is quest ID)
  2863.      &Spell::EffectForceCast,                                //140 SPELL_EFFECT_FORCE_CAST
  2864. -    &Spell::EffectNULL,                                     //141 SPELL_EFFECT_141                      damage and reduce speed?
  2865. +    &Spell::EffectForceCast,                                //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE                      damage and reduce speed?
  2866.      &Spell::EffectTriggerSpellWithValue,                    //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE
  2867.      &Spell::EffectApplyAreaAura,                            //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER
  2868.      &Spell::EffectKnockBackFromPosition,                    //144 SPELL_EFFECT_KNOCKBACK_FROM_POSITION
  2869. @@ -1930,6 +1931,28 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
  2870.  
  2871.                      return;
  2872.                  }
  2873. +                case 46292:                                 // Cataclysm Breath
  2874. +                {
  2875. +                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
  2876. +                        return;
  2877. +                    
  2878. +                    uint32 spellId = 0;
  2879. +                    
  2880. +                    switch (urand(0,7))
  2881. +                    {
  2882. +                        case 0: spellId = 46293; break; // Corrosive Poison
  2883. +                        case 1: spellId = 46294; break; // Fevered Fatigue
  2884. +                        case 2: spellId = 46295; break; // Hex
  2885. +                        case 3: spellId = 46296; break; // Necrotic Poison
  2886. +                        case 4: spellId = 46297; break; // Piercing Shadow
  2887. +                        case 5: spellId = 46298; break; // Shrink
  2888. +                        case 6: spellId = 46299; break; // Wavering Will
  2889. +                        case 7: spellId = 46300; break; // Withered Touch
  2890. +                    }
  2891. +                    
  2892. +                    m_caster->CastSpell(unitTarget, spellId, true);
  2893. +                    return;
  2894. +                }
  2895.                  case 46372:                                 // Ice Spear Target Picker
  2896.                  {
  2897.                      if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
  2898. @@ -3685,6 +3708,34 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
  2899.              // Death Strike
  2900.              else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000000010))
  2901.              {
  2902. +                
  2903. +                // Death Rune Mastery talents
  2904. +                if ((Player*)m_caster->HasSpell(49467))
  2905. +                {
  2906. +                    // 33% chance
  2907. +                    if (roll_chance_i(33))
  2908. +                    {
  2909. +                        for(uint8 i = 2; i <= 5; i++)
  2910. +                            ((Player*)m_caster)->ConvertRune(i, RUNE_DEATH);
  2911. +                        //((Player*)m_caster)->ConvertRune(2, RUNE_DEATH);
  2912. +                        //((Player*)m_caster)->ConvertRune(4, RUNE_DEATH);
  2913. +                    }
  2914. +                }
  2915. +                else if ((Player*)m_caster->HasSpell(50033))
  2916. +                {
  2917. +                    // 66% chance
  2918. +                    if (roll_chance_i(66))
  2919. +                    {
  2920. +                        for(uint8 i = 2; i <= 5; i++)
  2921. +                            ((Player*)m_caster)->ConvertRune(i, RUNE_DEATH);
  2922. +                    }
  2923. +                }
  2924. +                else if ((Player*)m_caster->HasSpell(50034))
  2925. +                {
  2926. +                    for(uint8 i = 2; i <= 5; i++)
  2927. +                            ((Player*)m_caster)->ConvertRune(i, RUNE_DEATH);
  2928. +                }      
  2929. +                
  2930.                  uint32 count = 0;
  2931.                  Unit::SpellAuraHolderMap const& auras = unitTarget->GetSpellAuraHolderMap();
  2932.                  for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
  2933. @@ -3739,6 +3790,32 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
  2934.              // Obliterate
  2935.              else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0002000000000000))
  2936.              {
  2937. +                
  2938. +                // Death Rune Mastery talents
  2939. +                if ((Player*)m_caster->HasSpell(49467))
  2940. +                {
  2941. +                    // 33% chance
  2942. +                    if (roll_chance_i(33))
  2943. +                    {
  2944. +                        for(uint8 i = 2; i <= 5; i++)
  2945. +                            ((Player*)m_caster)->ConvertRune(i, RUNE_DEATH);
  2946. +                    }
  2947. +                }
  2948. +                else if ((Player*)m_caster->HasSpell(50033))
  2949. +                {
  2950. +                    // 66% chance
  2951. +                    if (roll_chance_i(66))
  2952. +                    {
  2953. +                        for(uint8 i = 2; i <= 5; i++)
  2954. +                            ((Player*)m_caster)->ConvertRune(i, RUNE_DEATH);
  2955. +                    }
  2956. +                }
  2957. +                else if ((Player*)m_caster->HasSpell(50034))
  2958. +                {
  2959. +                    for(uint8 i = 2; i <= 5; i++)
  2960. +                        ((Player*)m_caster)->ConvertRune(i, RUNE_DEATH);
  2961. +                }      
  2962. +                
  2963.                  // search for Annihilation
  2964.                  Unit::AuraList const& dummyList = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
  2965.                  for (Unit::AuraList::const_iterator itr = dummyList.begin(); itr != dummyList.end(); ++itr)
  2966. @@ -3868,7 +3945,13 @@ void Spell::EffectForceCast(SpellEffectIndex eff_idx)
  2967.          return;
  2968.      }
  2969.  
  2970. -    unitTarget->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID, m_spellInfo);
  2971. +    int32 basePoints = damage;
  2972. +    
  2973. +    // spell effect 141 has BasePoints greater than 1
  2974. +    if (basePoints > 1)
  2975. +        unitTarget->CastCustomSpell(unitTarget, spellInfo, &basePoints, &basePoints, &basePoints, true, NULL , NULL, m_originalCasterGUID, m_spellInfo);
  2976. +    else
  2977. +        unitTarget->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID, m_spellInfo);
  2978.  }
  2979.  
  2980.  void Spell::EffectTriggerSpell(SpellEffectIndex effIndex)
  2981. @@ -3950,6 +4033,13 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex)
  2982.              }
  2983.              return;
  2984.          }
  2985. +        case 58832:                                         // Mirror Image
  2986. +        {
  2987. +            // Glyph of Mirror Image
  2988. +            if (m_caster->HasAura(63093))
  2989. +                m_caster->CastSpell(m_caster, 65047, true, m_CastItem, NULL, m_originalCasterGUID);
  2990. +            break;
  2991. +        }
  2992.      }
  2993.  
  2994.      // normal case
  2995. @@ -5322,6 +5412,13 @@ void Spell::EffectSummonType(SpellEffectIndex eff_idx)
  2996.                  ((Creature*)m_caster)->AI()->JustSummoned(itr->creature);
  2997.              if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI())
  2998.                  ((Creature*)m_originalCaster)->AI()->JustSummoned(itr->creature);
  2999. +        
  3000. +            // used by eluna
  3001. +            if (Unit* summoner = m_caster->ToUnit())
  3002. +                sEluna->OnSummoned(itr->creature, summoner);
  3003. +            else if (m_originalCaster)
  3004. +                if (Unit* summoner = m_originalCaster->ToUnit())
  3005. +                    sEluna->OnSummoned(itr->creature, summoner);
  3006.          }
  3007.      }
  3008.  }
  3009. @@ -5354,6 +5451,9 @@ bool Spell::DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry co
  3010.              // Notify original caster if not done already
  3011.              if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI())
  3012.                  ((Creature*)m_originalCaster)->AI()->JustSummoned(summon);
  3013. +        
  3014. +            if (Unit* summoner = m_originalCaster->ToUnit())
  3015. +                sEluna->OnSummoned(summon, summoner);
  3016.          }
  3017.          else
  3018.              return false;
  3019. @@ -5422,6 +5522,12 @@ bool Spell::DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry
  3020.          critter->SetDuration(m_duration);
  3021.  
  3022.      m_caster->SetMiniPet(critter);
  3023. +    
  3024. +    if (Unit* summoner = m_caster->ToUnit())
  3025. +        sEluna->OnSummoned(critter, summoner);
  3026. +    if (m_originalCaster)
  3027. +        if (Unit* summoner = m_originalCaster->ToUnit())
  3028. +            sEluna->OnSummoned(critter, summoner);
  3029.  
  3030.      return true;
  3031.  }
  3032. @@ -5495,6 +5601,12 @@ bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntr
  3033.          spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false);
  3034.  
  3035.          m_caster->AddGuardian(spawnCreature);
  3036. +        
  3037. +        if (Unit* summoner = m_caster->ToUnit())
  3038. +            sEluna->OnSummoned(spawnCreature, summoner);
  3039. +        if (m_originalCaster)
  3040. +            if (Unit* summoner = m_originalCaster->ToUnit())
  3041. +                sEluna->OnSummoned(spawnCreature, summoner);
  3042.      }
  3043.  
  3044.      return true;
  3045. @@ -5630,6 +5742,9 @@ bool Spell::DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEnt
  3046.      if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI())
  3047.          ((Creature*)m_originalCaster)->AI()->JustSummoned(spawnCreature);
  3048.  
  3049. +    if (Unit* summoner = m_originalCaster->ToUnit())
  3050. +        sEluna->OnSummoned(spawnCreature, summoner);
  3051. +    
  3052.      return true;
  3053.  }
  3054.  
  3055. @@ -5724,6 +5839,12 @@ bool Spell::DoSummonPet(SpellEffectIndex eff_idx)
  3056.      if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI())
  3057.          ((Creature*)m_originalCaster)->AI()->JustSummoned((Creature*)spawnCreature);
  3058.  
  3059. +    if (Unit* summoner = m_caster->ToUnit())
  3060. +        sEluna->OnSummoned(spawnCreature, summoner);
  3061. +    if (m_originalCaster)
  3062. +        if (Unit* summoner = m_originalCaster->ToUnit())
  3063. +            sEluna->OnSummoned(spawnCreature, summoner);
  3064. +        
  3065.      return false;
  3066.  }
  3067.  
  3068. @@ -5773,6 +5894,10 @@ bool Spell::DoSummonVehicle(CreatureSummonPositions& list, SummonPropertiesEntry
  3069.      if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI())
  3070.          ((Creature*)m_originalCaster)->AI()->JustSummoned(spawnCreature);
  3071.  
  3072. +    if (m_originalCaster)
  3073. +        if (Unit* summoner = m_originalCaster->ToUnit())
  3074. +            sEluna->OnSummoned(spawnCreature, summoner);
  3075. +        
  3076.      return true;
  3077.  }
  3078.  
  3079. @@ -7527,6 +7652,8 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
  3080.                      return;
  3081.                  }
  3082.                  case 41055:                                 // Copy Weapon
  3083. +                case 63416:                                 // Copy Weapon
  3084. +                case 69891:                                 // Copy Weapon (No Threat)
  3085.                  {
  3086.                      if (m_caster->GetTypeId() != TYPEID_UNIT || !unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
  3087.                          return;
  3088. @@ -7541,6 +7668,14 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
  3089.  
  3090.                      return;
  3091.                  }
  3092. +                case 41072:                                 // Bloodbolt
  3093. +                {
  3094. +                    if (!unitTarget)
  3095. +                        return;
  3096. +                    
  3097. +                    m_caster->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(eff_idx), true);
  3098. +                    return;
  3099. +                }
  3100.                  case 41126:                                 // Flame Crash
  3101.                  {
  3102.                      if (!unitTarget)
  3103. @@ -7549,6 +7684,17 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
  3104.                      unitTarget->CastSpell(unitTarget, 41131, true);
  3105.                      break;
  3106.                  }
  3107. +                case 42281:                                 // Sprouting
  3108. +                {
  3109. +                    if (!unitTarget)
  3110. +                        return;
  3111. +                    
  3112. +                    unitTarget->RemoveAurasDueToSpell(42280);
  3113. +                    unitTarget->RemoveAurasDueToSpell(42294);
  3114. +                    unitTarget->CastSpell(unitTarget, 42285, true);
  3115. +                    unitTarget->CastSpell(unitTarget, 42291, true);
  3116. +                    return;
  3117. +                }
  3118.                  case 43365:                                 // The Cleansing: Shrine Cast
  3119.                  {
  3120.                      if (m_caster->GetTypeId() != TYPEID_PLAYER)
  3121. @@ -7730,6 +7876,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
  3122.                      return;
  3123.                  }
  3124.                  case 45206:                                 // Copy Off-hand Weapon
  3125. +                case 69892:                                 // Copy Off-hand Weapon (No Threat)
  3126.                  {
  3127.                      if (m_caster->GetTypeId() != TYPEID_UNIT || !unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
  3128.                          return;
  3129. @@ -9404,6 +9551,59 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
  3130.  
  3131.                      break;
  3132.                  }
  3133. +                case 46584:                                   // Raise dead
  3134. +                {
  3135. +                    if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER)
  3136. +                        return;
  3137. +                    
  3138. +                    // If DK has spell 52143, summon pet from dummy effect
  3139. +                    // otherwise summon guardian
  3140. +                    uint32 triggered_spell_id = m_spellInfo->CalculateSimpleValue(SpellEffectIndex(m_caster->HasSpell(52143) ? EFFECT_INDEX_2 : EFFECT_INDEX_1));
  3141. +                
  3142. +                    float x,y,z;
  3143. +                    m_caster->GetClosePoint(x, y, z, m_caster->GetObjectBoundingRadius(), PET_FOLLOW_DIST);
  3144. +                
  3145. +                    if (unitTarget != (Unit*)m_caster)
  3146. +                        m_caster->CastSpell(unitTarget->GetPositionX(),unitTarget->GetPositionY(),unitTarget->GetPositionZ(),triggered_spell_id, true, NULL, NULL, m_caster->GetObjectGuid(), m_spellInfo);
  3147. +                    else if (m_caster->HasAura(60200))
  3148. +                        m_caster->CastSpell(x,y,z,triggered_spell_id, true, NULL, NULL, m_caster->GetObjectGuid(), m_spellInfo);
  3149. +                    else if (((Player*)m_caster)->HasItemCount(37201,1))
  3150. +                    {
  3151. +                        ((Player*)m_caster)->DestroyItemCount(37201, 1, true);
  3152. +                        m_caster->CastSpell(m_caster,48289,true);
  3153. +                        m_caster->CastSpell(x,y,z,triggered_spell_id, true, NULL, NULL, m_caster->GetObjectGuid(), m_spellInfo);
  3154. +                    }
  3155. +                    else
  3156. +                    {
  3157. +                        SendCastResult(SPELL_FAILED_REAGENTS);
  3158. +                        finish(true);
  3159. +                        CancelGlobalCooldown();
  3160. +                        return;
  3161. +                    }
  3162. +                    finish(true);
  3163. +                    ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_2),true);
  3164. +                    ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_1),true);
  3165. +                    //CancelGlobalCooldown();
  3166. +                    return;
  3167. +                }
  3168. +                case 61999:                                                 // Raise ally
  3169. +                {
  3170. +                    if (m_caster->GetTypeId() != TYPEID_PLAYER)
  3171. +                        return;
  3172. +                    
  3173. +                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || unitTarget->isAlive())
  3174. +                    {
  3175. +                        SendCastResult(SPELL_FAILED_TARGET_NOT_DEAD);
  3176. +                        finish(true);
  3177. +                        CancelGlobalCooldown();
  3178. +                        return;
  3179. +                    }
  3180. +                    
  3181. +                    // hacky remove death
  3182. +                    unitTarget->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(EFFECT_INDEX_0), true);
  3183. +                    CancelGlobalCooldown();
  3184. +                    return;
  3185. +                }
  3186.              }
  3187.              break;
  3188.          }
  3189. @@ -9534,6 +9734,9 @@ void Spell::EffectDuel(SpellEffectIndex eff_idx)
  3190.  
  3191.      caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetObjectGuid());
  3192.      target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetObjectGuid());
  3193. +    
  3194. +    // used by eluna
  3195. +    sEluna->OnDuelRequest(target, caster);
  3196.  }
  3197.  
  3198.  void Spell::EffectStuck(SpellEffectIndex /*eff_idx*/)
  3199. @@ -10658,7 +10861,10 @@ void Spell::EffectWMODamage(SpellEffectIndex effIdx)
  3200.  {
  3201.      DEBUG_LOG("Effect: WMODamage");
  3202.  
  3203. -    if (!gameObjTarget || gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3204. +    if (!gameObjTarget)
  3205. +        return;
  3206. +    
  3207. +    if (gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3208.      {
  3209.          sLog.outError("Spell::EffectWMODamage called without valid targets. Spell Id %u", m_spellInfo->Id);
  3210.          return;
  3211. @@ -10678,8 +10884,11 @@ void Spell::EffectWMODamage(SpellEffectIndex effIdx)
  3212.  void Spell::EffectWMORepair(SpellEffectIndex effIdx)
  3213.  {
  3214.      DEBUG_LOG("Effect: WMORepair");
  3215. +    
  3216. +    if (!gameObjTarget)
  3217. +        return;
  3218.  
  3219. -    if (!gameObjTarget || gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3220. +    if (gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3221.      {
  3222.          sLog.outError("Spell::EffectWMORepair called without valid targets. Spell Id %u", m_spellInfo->Id);
  3223.          return;
  3224. @@ -10696,8 +10905,11 @@ void Spell::EffectWMORepair(SpellEffectIndex effIdx)
  3225.  void Spell::EffectWMOChange(SpellEffectIndex effIdx)
  3226.  {
  3227.      DEBUG_LOG("Effect: WMOChange");
  3228. +    
  3229. +    if (!gameObjTarget)
  3230. +        return;
  3231.  
  3232. -    if (!gameObjTarget || gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3233. +    if (gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
  3234.      {
  3235.          sLog.outError("Spell::EffectWMOChange called without valid targets. Spell Id %u", m_spellInfo->Id);
  3236.          return;
  3237. diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
  3238. index 4e2afdd..8760a6f 100644
  3239. --- a/src/game/SpellHandler.cpp
  3240. +++ b/src/game/SpellHandler.cpp
  3241. @@ -617,10 +617,16 @@ void WorldSession::HandleSpellClick(WorldPacket& recv_data)
  3242.      {
  3243.          if (itr->second.IsFitToRequirements(_player, unit))
  3244.          {
  3245. +            if (sScriptMgr.OnNpcSpellClick(_player, unit, itr->second.spellId))
  3246. +                return;
  3247. +            
  3248.              Unit* caster = (itr->second.castFlags & 0x1) ? (Unit*)_player : (Unit*)unit;
  3249.              Unit* target = (itr->second.castFlags & 0x2) ? (Unit*)_player : (Unit*)unit;
  3250.  
  3251. -            caster->CastSpell(target, itr->second.spellId, true);
  3252. +            if (itr->second.spellId)
  3253. +                caster->CastSpell(target, itr->second.spellId, true);
  3254. +            else
  3255. +                sLog.outError("WorldSession::HandleSpellClick: npc_spell_click with entry %u has 0 in spell_id. Not handled custom case?", unit->GetEntry());
  3256.          }
  3257.      }
  3258.  }
  3259. diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp
  3260. index b09b328..aea4bd7 100644
  3261. --- a/src/game/Totem.cpp
  3262. +++ b/src/game/Totem.cpp
  3263. @@ -25,6 +25,7 @@
  3264.  #include "SpellMgr.h"
  3265.  #include "CreatureAI.h"
  3266.  #include "InstanceData.h"
  3267. +#include "LuaEngine.h"
  3268.  
  3269.  Totem::Totem() : Creature(CREATURE_SUBTYPE_TOTEM)
  3270.  {
  3271. @@ -96,6 +97,7 @@ void Totem::Summon(Unit* owner)
  3272.  
  3273.      if (owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->AI())
  3274.          ((Creature*)owner)->AI()->JustSummoned((Creature*)this);
  3275. +    sEluna->OnSummoned(this, owner);
  3276.  
  3277.      // there are some totems, which exist just for their visual appeareance
  3278.      if (!GetSpell())
  3279. diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
  3280. index 24743d8..84148e5 100644
  3281. --- a/src/game/Unit.cpp
  3282. +++ b/src/game/Unit.cpp
  3283. @@ -51,6 +51,7 @@
  3284.  #include "movement/MoveSplineInit.h"
  3285.  #include "movement/MoveSpline.h"
  3286.  #include "CreatureLinkingMgr.h"
  3287. +#include "LuaEngine.h"
  3288.  
  3289.  #include <math.h>
  3290.  #include <stdarg.h>
  3291. @@ -274,6 +275,8 @@ Unit::Unit() :
  3292.  
  3293.  Unit::~Unit()
  3294.  {
  3295. +    Eluna::RemoveRef(this);
  3296. +    
  3297.      // set current spells as deletable
  3298.      for (uint32 i = 0; i < CURRENT_MAX_SPELL; ++i)
  3299.      {
  3300. @@ -802,6 +805,13 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
  3301.          // Call KilledUnit for creatures
  3302.          if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
  3303.              ((Creature*)this)->AI()->KilledUnit(pVictim);
  3304. +        
  3305. +        if (Creature* killer = ToCreature())
  3306. +        {
  3307. +            // used by eluna
  3308. +            if (Player* killed = pVictim->ToPlayer())
  3309. +                sEluna->OnPlayerKilledByCreature(killer, killed);
  3310. +        }
  3311.  
  3312.          // Call AI OwnerKilledUnit (for any current summoned minipet/guardian/protector)
  3313.          PetOwnerKilledUnit(pVictim);
  3314. @@ -866,6 +876,9 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
  3315.                      if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(playerVictim->GetCachedZoneId()))
  3316.                          outdoorPvP->HandlePlayerKill(player_tap, playerVictim);
  3317.                  }
  3318. +                
  3319. +                // used by eluna
  3320. +                sEluna->OnPVPKill(player_tap, playerVictim);
  3321.              }
  3322.          }
  3323.          else                                                // Killed creature
  3324. @@ -1062,8 +1075,14 @@ void Unit::JustKilledCreature(Creature* victim, Player* responsiblePlayer)
  3325.          mapInstance->OnCreatureDeath(victim);
  3326.  
  3327.      if (responsiblePlayer)                                  // killedby Player, inform BG
  3328. +    {
  3329.          if (BattleGround* bg = responsiblePlayer->GetBattleGround())
  3330.              bg->HandleKillUnit(victim, responsiblePlayer);
  3331. +        
  3332. +        // used by eluna
  3333. +        sEluna->OnCreatureKill(responsiblePlayer, victim);
  3334. +    }
  3335. +    
  3336.      // Notify the outdoor pvp script
  3337.      if (OutdoorPvP* outdoorPvP = sOutdoorPvPMgr.GetScript(responsiblePlayer ? responsiblePlayer->GetCachedZoneId() : GetZoneId()))
  3338.          outdoorPvP->HandleCreatureDeath(victim);
  3339. @@ -7979,6 +7998,9 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
  3340.  
  3341.      if (PvP)
  3342.          m_CombatTimer = 5000;
  3343. +    
  3344. +    if (isInCombat())
  3345. +        return;
  3346.  
  3347.      bool creatureNotInCombat = GetTypeId() == TYPEID_UNIT && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
  3348.  
  3349. @@ -8017,6 +8039,10 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
  3350.          if (m_isCreatureLinkingTrigger)
  3351.              GetMap()->GetCreatureLinkingHolder()->DoCreatureLinkingEvent(LINKING_EVENT_AGGRO, pCreature, enemy);
  3352.      }
  3353. +    
  3354. +    // used by eluna
  3355. +    if (GetTypeId() == TYPEID_PLAYER)
  3356. +        sEluna->OnPlayerEnterCombat(ToPlayer(), enemy);
  3357.  }
  3358.  
  3359.  void Unit::ClearInCombat()
  3360. @@ -8026,6 +8052,9 @@ void Unit::ClearInCombat()
  3361.  
  3362.      if (isCharmed() || (GetTypeId() != TYPEID_PLAYER && ((Creature*)this)->IsPet()))
  3363.          RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT);
  3364. +    
  3365. +    if (GetTypeId() == TYPEID_PLAYER)
  3366. +        sEluna->OnPlayerLeaveCombat(ToPlayer());
  3367.  
  3368.      // Player's state will be cleared in Player::UpdateContestedPvP
  3369.      if (GetTypeId() == TYPEID_UNIT)
  3370. @@ -10842,6 +10871,24 @@ void Unit::SetFFAPvP(bool state)
  3371.      CallForAllControlledUnits(SetFFAPvPHelper(state), CONTROLLED_PET | CONTROLLED_TOTEMS | CONTROLLED_GUARDIANS | CONTROLLED_CHARM);
  3372.  }
  3373.  
  3374. +void Unit::RestoreOriginalFaction()
  3375. +{
  3376. +    if (GetTypeId() == TYPEID_PLAYER)
  3377. +        ((Player*)this)->setFactionForRace(getRace());
  3378. +    else
  3379. +    {
  3380. +        Creature* creature = (Creature*)this;
  3381. +        
  3382. +        if (creature->IsPet() || creature->IsTotem())
  3383. +        {
  3384. +            if (Unit* owner = GetOwner())
  3385. +                setFaction(owner->getFaction());
  3386. +        }
  3387. +        else
  3388. +            setFaction(creature->GetCreatureInfo()->FactionAlliance);
  3389. +    }
  3390. +}
  3391. +
  3392.  void Unit::KnockBackFrom(Unit* target, float horizontalSpeed, float verticalSpeed)
  3393.  {
  3394.      float angle = this == target ? GetOrientation() + M_PI_F : target->GetAngle(this);
  3395. diff --git a/src/game/Unit.h b/src/game/Unit.h
  3396. index 5ddddef..5b31bd2 100644
  3397. --- a/src/game/Unit.h
  3398. +++ b/src/game/Unit.h
  3399. @@ -412,6 +412,7 @@ enum DeathState
  3400.      CORPSE         = 2,                                     // corpse state, for player this also meaning that player not leave corpse
  3401.      DEAD           = 3,                                     // for creature despawned state (corpse despawned), for player CORPSE/DEAD not clear way switches (FIXME), and use m_deathtimer > 0 check for real corpse state
  3402.      JUST_ALIVED    = 4,                                     // temporary state at resurrection, for creature auto converted to ALIVE, for player at next update call
  3403. +    GHOULED        = 5,                                     // death knight related
  3404.  };
  3405.  
  3406.  // internal state flags for some auras and movement generators, other.
  3407. @@ -1627,6 +1628,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  3408.           * \see GetMaxHealth
  3409.           */
  3410.          float GetHealthPercent() const { return (GetHealth() * 100.0f) / GetMaxHealth(); }
  3411. +        
  3412. +        uint32 CountPctFromMaxHealth(int32 pct) const { return (GetMaxHealth() * static_cast<float>(pct) / 100.0f); }
  3413. +        uint32 CountPctFromCurHealth(int32 pct) const { return (GetHealth() * static_cast<float>(pct) / 100.0f); }
  3414. +        
  3415.          /**
  3416.           * Sets the health to the given value, it cant be higher than Unit::GetMaxHealth though
  3417.           * @param val the value to set the health to
  3418. @@ -1654,6 +1659,13 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  3419.           */
  3420.          int32 ModifyHealth(int32 val);
  3421.  
  3422. +        // Eluna-related health functions
  3423. +        bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); }
  3424. +        bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); }
  3425. +        bool HealthBelowPct(int32 pct) const { return GetHealth() < CountPctFromMaxHealth(pct); }
  3426. +        bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); }
  3427. +        bool HealthAbovePct(int32 pct) const { return GetHealth() > CountPctFromMaxHealth(pct); }
  3428. +        
  3429.          /**
  3430.           * Gets the power type for this Unit
  3431.           * @return The type of power this Unit uses
  3432. @@ -1752,6 +1764,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  3433.           */
  3434.          void setFaction(uint32 faction) { SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction); }
  3435.          FactionTemplateEntry const* getFactionTemplateEntry() const;
  3436. +        void RestoreOriginalFaction();
  3437.          /**
  3438.           * Are we hostile towards the given Unit?
  3439.           * @param unit the unit we want to check against
  3440. @@ -2202,6 +2215,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  3441.  
  3442.          bool isAlive() const { return (m_deathState == ALIVE); };
  3443.          bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); };
  3444. +        bool isDying() const { return (m_deathState == JUST_DIED); }
  3445.          DeathState getDeathState() const { return m_deathState; };
  3446.          virtual void SetDeathState(DeathState s);           // overwritten in Creature/Player/Pet
  3447.  
  3448. @@ -2360,6 +2374,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
  3449.          void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0);
  3450.  
  3451.          Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
  3452. +        Spell* GetCurrentSpell(uint32 spellType) const { return m_currentSpells[spellType]; }
  3453.          Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
  3454.  
  3455.          bool CheckAndIncreaseCastCounter();
  3456. diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp
  3457. index f275015..d1502bd 100644
  3458. --- a/src/game/Vehicle.cpp
  3459. +++ b/src/game/Vehicle.cpp
  3460. @@ -46,6 +46,7 @@
  3461.  #include "movement/MoveSpline.h"
  3462.  #include "MapManager.h"
  3463.  #include "TemporarySummon.h"
  3464. +#include "LuaEngine.h"
  3465.  
  3466.  void ObjectMgr::LoadVehicleAccessory()
  3467.  {
  3468. @@ -118,6 +119,8 @@ VehicleInfo::VehicleInfo(Unit* owner, VehicleEntry const* vehicleEntry, uint32 o
  3469.  
  3470.  VehicleInfo::~VehicleInfo()
  3471.  {
  3472. +    Eluna::RemoveRef(this);
  3473. +    
  3474.      ((Unit*)m_owner)->RemoveSpellsCausingAura(SPELL_AURA_CONTROL_VEHICLE);
  3475.  
  3476.      RemoveAccessoriesFromMap();                             // Remove accessories (for example required with player vehicles)
  3477. @@ -138,9 +141,36 @@ void VehicleInfo::Initialize()
  3478.              m_accessoryGuids.insert(summoned->GetObjectGuid());
  3479.              int32 basepoint0 = itr->seatId + 1;
  3480.              summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, NULL, NULL, true);
  3481. +        
  3482. +            sEluna->OnInstallAccessory(this, summoned);
  3483.          }
  3484.      }
  3485. +    
  3486. +    // Initialize movement limitations
  3487. +   /* uint32 vehicleFlags = GetVehicleEntry()->m_flags;
  3488. +    Unit* pVehicle = (Unit*)m_owner;
  3489. +    
  3490. +    if (vehicleFlags & VEHICLE_FLAG_NO_STRAFE)
  3491. +        pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_STRAFE);
  3492. +    if (vehicleFlags & VEHICLE_FLAG_NO_JUMPING)
  3493. +        pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_NO_JUMPING);
  3494. +    if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDTURNING)
  3495. +        pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDTURNING);
  3496. +    if (vehicleFlags & VEHICLE_FLAG_ALLOW_PITCHING)
  3497. +        pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_ALLOW_PITCHING);
  3498. +    if (vehicleFlags & VEHICLE_FLAG_FULLSPEEDPITCHING)
  3499. +        pVehicle->m_movementInfo.AddMovementFlags2(MOVEFLAG2_FULLSPEEDPITCHING);
  3500. +    
  3501. +    // Initialize power type based on DBC values (creatures only)
  3502. +    if (pVehicle->GetTypeId() == TYPEID_UNIT)
  3503. +    {
  3504. +        if (PowerDisplayEntry const* powerEntry = sPowerDisplayStore.LookupEntry(GetVehicleEntry()->m_powerDisplayID))
  3505. +            pVehicle->SetPowerType(Powers(powerEntry->power));
  3506. +    }*/
  3507. +    
  3508.      m_isInitialized = true;
  3509. +    
  3510. +    sEluna->OnInstall(this);
  3511.  }
  3512.  
  3513.  /*
  3514. @@ -212,6 +242,8 @@ void VehicleInfo::Board(Unit* passenger, uint8 seat)
  3515.  
  3516.      // Apply passenger modifications
  3517.      ApplySeatMods(passenger, seatEntry->m_flags);
  3518. +    
  3519. +    sEluna->OnAddPassenger(this, passenger, seat);
  3520.  }
  3521.  
  3522.  /*
  3523. @@ -325,6 +357,8 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle)
  3524.  
  3525.      // Remove passenger modifications
  3526.      RemoveSeatMods(passenger, seatEntry->m_flags);
  3527. +    
  3528. +    sEluna->OnRemovePassenger(this, passenger);
  3529.  
  3530.      // Some creature vehicles get despawned after passenger unboarding
  3531.      if (m_owner->GetTypeId() == TYPEID_UNIT)
  3532. diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h
  3533. index c1dd877..93c8362 100644
  3534. --- a/src/game/Vehicle.h
  3535. +++ b/src/game/Vehicle.h
  3536. @@ -68,7 +68,8 @@ class VehicleInfo : public TransportBase
  3537.          ~VehicleInfo();
  3538.  
  3539.          VehicleEntry const* GetVehicleEntry() const { return m_vehicleEntry; }
  3540. -
  3541. +        VehicleSeatEntry const* GetSeatEntry(uint8 seat) const;
  3542. +        
  3543.          void Board(Unit* passenger, uint8 seat);            // Board a passenger to a vehicle
  3544.          void SwitchSeat(Unit* passenger, uint8 seat);       // Used to switch seats of a passenger
  3545.          void UnBoard(Unit* passenger, bool changeVehicle);  // Used to Unboard a passenger from a vehicle
  3546. @@ -83,7 +84,6 @@ class VehicleInfo : public TransportBase
  3547.          void CalculateBoardingPositionOf(float gx, float gy, float gz, float go, float& lx, float& ly, float& lz, float& lo) const;
  3548.  
  3549.          // Seat information
  3550. -        VehicleSeatEntry const* GetSeatEntry(uint8 seat) const;
  3551.          bool GetUsableSeatFor(Unit* passenger, uint8& seat) const;
  3552.          bool IsSeatAvailableFor(Unit* passenger, uint8 seat) const;
  3553.  
  3554. diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp
  3555. index 7002212..1597f59 100644
  3556. --- a/src/game/Weather.cpp
  3557. +++ b/src/game/Weather.cpp
  3558. @@ -27,6 +27,7 @@
  3559.  #include "Log.h"
  3560.  #include "ObjectMgr.h"
  3561.  #include "Util.h"
  3562. +#include "LuaEngine.h"
  3563.  
  3564.  /// Create the Weather object
  3565.  Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone(zone), m_weatherChances(weatherChances)
  3566. @@ -38,6 +39,11 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone
  3567.      DETAIL_FILTER_LOG(LOG_FILTER_WEATHER, "WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (m_timer.GetInterval() / (MINUTE * IN_MILLISECONDS)));
  3568.  }
  3569.  
  3570. +Weather::~Weather()
  3571. +{
  3572. +    Eluna::RemoveRef(this);
  3573. +}
  3574. +
  3575.  /// Launch a weather update
  3576.  bool Weather::Update(time_t diff)
  3577.  {
  3578. @@ -261,6 +267,7 @@ bool Weather::UpdateWeather()
  3579.      }
  3580.  
  3581.      DETAIL_FILTER_LOG(LOG_FILTER_WEATHER, "Change the weather of zone %u to %s.", m_zone, wthstr);
  3582. +    sEluna->OnChange(this, (WeatherState)m_type, m_grade);
  3583.  
  3584.      return true;
  3585.  }
  3586. diff --git a/src/game/Weather.h b/src/game/Weather.h
  3587. index 1680e30..53c1c47 100644
  3588. --- a/src/game/Weather.h
  3589. +++ b/src/game/Weather.h
  3590. @@ -52,7 +52,7 @@ class Weather
  3591.  {
  3592.      public:
  3593.          Weather(uint32 zone, WeatherZoneChances const* weatherChances);
  3594. -        ~Weather() { };
  3595. +        ~Weather();
  3596.          bool ReGenerate();
  3597.          bool UpdateWeather();
  3598.          void SendWeatherUpdateToPlayer(Player* player);
  3599. diff --git a/src/game/World.cpp b/src/game/World.cpp
  3600. index b67e09e..cd7dc50 100644
  3601. --- a/src/game/World.cpp
  3602. +++ b/src/game/World.cpp
  3603. @@ -67,6 +67,7 @@
  3604.  #include "CharacterDatabaseCleaner.h"
  3605.  #include "CreatureLinkingMgr.h"
  3606.  #include "Calendar.h"
  3607. +#include "LuaEngine.h"
  3608.  
  3609.  INSTANTIATE_SINGLETON_1(World);
  3610.  
  3611. @@ -150,6 +151,8 @@ void World::CleanupsBeforeStop()
  3612.      KickAll();                                       // save and kick all players
  3613.      UpdateSessions(1);                               // real players unload required UpdateSessions call
  3614.      sBattleGroundMgr.DeleteAllBattleGrounds();       // unload battleground templates before different singletons destroyed
  3615. +
  3616. +    Eluna::Uninitialize();
  3617.  }
  3618.  
  3619.  /// Find a player in a specified zone
  3620. @@ -919,6 +922,8 @@ void World::LoadConfigSettings(bool reload)
  3621.      std::string ignoreMapIds = sConfig.GetStringDefault("mmap.ignoreMapIds", "");
  3622.      MMAP::MMapFactory::preventPathfindingOnMaps(ignoreMapIds.c_str());
  3623.      sLog.outString("WORLD: mmap pathfinding %sabled", getConfig(CONFIG_BOOL_MMAP_ENABLED) ? "en" : "dis");
  3624. +
  3625. +    setConfig(CONFIG_BOOL_ELUNA_ENABLED, "Eluna.Enabled", true);
  3626.  }
  3627.  
  3628.  /// Initialize the World
  3629. @@ -1363,6 +1368,10 @@ void World::SetInitialWorldSettings()
  3630.              sLog.outError("Scripting library build for old mangosd revision. You need rebuild it.");
  3631.              break;
  3632.      }
  3633. +    
  3634. +    ///- Initialize Lua Engine
  3635. +    sLog.outString("Initialize Eluna Lua Engine...");
  3636. +    Eluna::Initialize();
  3637.  
  3638.      ///- Initialize game time and timers
  3639.      sLog.outString("DEBUG:: Initialize game time and timers");
  3640. @@ -1591,6 +1600,9 @@ void World::Update(uint32 diff)
  3641.      sMapMgr.Update(diff);
  3642.      sBattleGroundMgr.Update(diff);
  3643.      sOutdoorPvPMgr.Update(diff);
  3644. +    
  3645. +    ///- Used by Eluna
  3646. +    sEluna->OnWorldUpdate(diff);
  3647.  
  3648.      ///- Delete all characters which have been deleted X days before
  3649.      if (m_timers[WUPDATE_DELETECHARS].Passed())
  3650. @@ -2181,7 +2193,7 @@ void World::InitRandomBGResetTime()
  3651.      // normalize reset time
  3652.      m_NextRandomBGReset = m_NextRandomBGReset < curTime ? nextDayResetTime - DAY : nextDayResetTime;
  3653.      if (!result)
  3654. -        CharacterDatabase.PExecute("INSERT INTO saved_variables (NextRandomBGResetTime) VALUES ('"UI64FMTD"')", uint64(m_NextRandomBGReset));
  3655. +        CharacterDatabase.PExecute("INSERT INTO saved_variables (NextRandomBGResetTime) VALUES ('" UI64FMTD "')", uint64(m_NextRandomBGReset));
  3656.      else
  3657.          delete result;
  3658.  }
  3659. @@ -2207,7 +2219,7 @@ void World::ResetRandomBG()
  3660.              itr->second->GetPlayer()->SetRandomWinner(false);
  3661.  
  3662.      m_NextRandomBGReset = time_t(m_NextRandomBGReset + DAY);
  3663. -    CharacterDatabase.PExecute("UPDATE saved_variables SET NextRandomBGResetTime = '"UI64FMTD"'", uint64(m_NextRandomBGReset));
  3664. +    CharacterDatabase.PExecute("UPDATE saved_variables SET NextRandomBGResetTime = '" UI64FMTD "'", uint64(m_NextRandomBGReset));
  3665.  }
  3666.  
  3667.  void World::ResetWeeklyQuests()
  3668. diff --git a/src/game/World.h b/src/game/World.h
  3669. index e67c504..51834ce 100644
  3670. --- a/src/game/World.h
  3671. +++ b/src/game/World.h
  3672. @@ -345,6 +345,7 @@ enum eConfigBoolValues
  3673.      CONFIG_BOOL_VMAP_INDOOR_CHECK,
  3674.      CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT,
  3675.      CONFIG_BOOL_MMAP_ENABLED,
  3676. +    CONFIG_BOOL_ELUNA_ENABLED,
  3677.      CONFIG_BOOL_PLAYER_COMMANDS,
  3678.      CONFIG_BOOL_VALUE_COUNT
  3679.  };
  3680. @@ -444,6 +445,9 @@ struct CliCommandHolder
  3681.  };
  3682.  
  3683.  /// The World
  3684. +
  3685. +typedef UNORDERED_MAP<uint32, WorldSession*> SessionMap;
  3686. +
  3687.  class World
  3688.  {
  3689.      public:
  3690. @@ -459,6 +463,7 @@ class World
  3691.          bool RemoveSession(uint32 id);
  3692.          /// Get the number of current active sessions
  3693.          void UpdateMaxSessionCounters();
  3694. +        const SessionMap& GetAllSessions() const { return m_sessions; }
  3695.          uint32 GetActiveAndQueuedSessionCount() const { return m_sessions.size(); }
  3696.          uint32 GetActiveSessionCount() const { return m_sessions.size() - m_QueuedSessions.size(); }
  3697.          uint32 GetQueuedSessionCount() const { return m_QueuedSessions.size(); }
  3698. diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp
  3699. index 8966566..a36237f 100644
  3700. --- a/src/game/WorldSession.cpp
  3701. +++ b/src/game/WorldSession.cpp
  3702. @@ -39,6 +39,7 @@
  3703.  #include "Auth/AuthCrypt.h"
  3704.  #include "Auth/HMACSHA1.h"
  3705.  #include "zlib/zlib.h"
  3706. +#include "LuaEngine.h"
  3707.  
  3708.  // select opcodes appropriate for processing in Map::Update context for current session state
  3709.  static bool MapSessionFilterHelper(WorldSession* session, OpcodeHandler const& opHandle)
  3710. @@ -463,6 +464,9 @@ void WorldSession::LogoutPlayer(bool Save)
  3711.          ///- Broadcast a logout message to the player's friends
  3712.          sSocialMgr.SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetObjectGuid(), true);
  3713.          sSocialMgr.RemovePlayerSocial(_player->GetGUIDLow());
  3714. +        
  3715. +        ///- Used by Eluna
  3716. +        sEluna->OnLogout(_player);
  3717.  
  3718.          ///- Remove the player from the world
  3719.          // the player may not be in the world when logging out
  3720. @@ -962,6 +966,9 @@ void WorldSession::SendRedirectClient(std::string& ip, uint16 port)
  3721.  
  3722.  void WorldSession::ExecuteOpcode(OpcodeHandler const& opHandle, WorldPacket* packet)
  3723.  {
  3724. +    if (!sEluna->OnPacketReceive(this, *packet))
  3725. +        return;
  3726. +    
  3727.      // need prevent do internal far teleports in handlers because some handlers do lot steps
  3728.      // or call code that can do far teleports in some conditions unexpectedly for generic way work code
  3729.      if (_player)
  3730. diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
  3731. index be2fb4f..f8ef946 100644
  3732. --- a/src/game/WorldSession.h
  3733. +++ b/src/game/WorldSession.h
  3734. @@ -250,6 +250,7 @@ class MANGOS_DLL_SPEC WorldSession
  3735.          void SendLfgUpdate(bool isGroup, LfgUpdateType updateType, uint32 id);
  3736.          void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
  3737.          void SendGroupInvite(Player* player, bool alreadyInGroup = false);
  3738. +        void SendGuildInvite(Player* player, bool alreadyInGuild = false);
  3739.          void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3);
  3740.          void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0);
  3741.          void SendSetPhaseShift(uint32 phaseShift);
  3742. diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp
  3743. index 74d1acc..728a685 100644
  3744. --- a/src/game/WorldSocket.cpp
  3745. +++ b/src/game/WorldSocket.cpp
  3746. @@ -42,6 +42,7 @@
  3747.  #include "WorldSocketMgr.h"
  3748.  #include "Log.h"
  3749.  #include "DBCStores.h"
  3750. +#include "LuaEngine.h"
  3751.  
  3752.  #if defined( __GNUC__ )
  3753.  #pragma pack(1)
  3754. @@ -156,16 +157,21 @@ const std::string& WorldSocket::GetRemoteAddress(void) const
  3755.      return m_Address;
  3756.  }
  3757.  
  3758. -int WorldSocket::SendPacket(const WorldPacket& pct)
  3759. +int WorldSocket::SendPacket(const WorldPacket& pkt)
  3760.  {
  3761.      ACE_GUARD_RETURN(LockType, Guard, m_OutBufferLock, -1);
  3762.  
  3763.      if (closing_)
  3764.          return -1;
  3765. +    
  3766. +    WorldPacket pct = pkt;
  3767.  
  3768.      // Dump outgoing packet.
  3769.      sLog.outWorldPacketDump(uint32(get_handle()), pct.GetOpcode(), pct.GetOpcodeName(), &pct, false);
  3770.  
  3771. +    if (!sEluna->OnPacketSend(m_Session, pct))
  3772. +        return 0;
  3773. +    
  3774.      ServerPktHeader header(pct.size() + 2, pct.GetOpcode());
  3775.      m_Crypt.EncryptSend((uint8*)header.header, header.getHeaderLength());
  3776.  
  3777. @@ -687,11 +693,14 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
  3778.                      sLog.outError("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
  3779.                      return -1;
  3780.                  }
  3781. -
  3782. +                
  3783. +                if (!sEluna->OnPacketReceive(m_Session, *new_pct))
  3784. +                    return 0;
  3785.                  return HandleAuthSession(*new_pct);
  3786.              case CMSG_KEEP_ALIVE:
  3787.                  DEBUG_LOG("CMSG_KEEP_ALIVE ,size: " SIZEFMTD " ", new_pct->size());
  3788.  
  3789. +                sEluna->OnPacketReceive(m_Session, *new_pct);
  3790.                  return 0;
  3791.              default:
  3792.              {
  3793. diff --git a/src/game/vmap/RegularGrid.h b/src/game/vmap/RegularGrid.h
  3794. index d15e79f..dbaa501 100644
  3795. --- a/src/game/vmap/RegularGrid.h
  3796. +++ b/src/game/vmap/RegularGrid.h
  3797. @@ -107,7 +107,7 @@ class RegularGrid2D
  3798.  
  3799.              static Cell ComputeCell(float fx, float fy)
  3800.              {
  3801. -                Cell c = {fx* (1.f / CELL_SIZE) + (CELL_NUMBER / 2), fy* (1.f / CELL_SIZE) + (CELL_NUMBER / 2)};
  3802. +                Cell c = {static_cast<int>(fx* (1.f / CELL_SIZE) + (CELL_NUMBER / 2)), static_cast<int>(fy* (1.f / CELL_SIZE) + (CELL_NUMBER / 2))};
  3803.                  return c;
  3804.              }
  3805.  
  3806. diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in
  3807. index ee6066f..8c50348 100644
  3808. --- a/src/mangosd/mangosd.conf.dist.in
  3809. +++ b/src/mangosd/mangosd.conf.dist.in
  3810. @@ -305,6 +305,10 @@ CleanCharacterDB = 1
  3811.  #        Log file of DB errors detected at server run
  3812.  #        Default: "DBErrors.log"
  3813.  #
  3814. +#    ElunaErrorLogFile
  3815. +#        Log file of Eluna errors detected at server run
  3816. +#        Default: "ElunaErrors.log"
  3817. +#
  3818.  #    EventAIErrorLogFile
  3819.  #        Log file of EventAI errors detected at server run
  3820.  #        Default: "EventAIErrors.log"
  3821. @@ -384,6 +388,7 @@ LogFilter_Calendar = 1
  3822.  WorldLogFile = ""
  3823.  WorldLogTimestamp = 0
  3824.  DBErrorLogFile = "DBErrors.log"
  3825. +ElunaErrorLogFile = "ElunaErrors.log"
  3826.  EventAIErrorLogFile = "EventAIErrors.log"
  3827.  CharLogFile = "Char.log"
  3828.  CharLogTimestamp = 0
  3829. @@ -1717,3 +1722,19 @@ SOAP.Port = 7878
  3830.  CharDelete.Method = 0
  3831.  CharDelete.MinLevel = 0
  3832.  CharDelete.KeepDays = 30
  3833. +
  3834. +###################################################################################################################
  3835. +# ELUNA SETTINGS
  3836. +#
  3837. +#    Eluna.Enabled
  3838. +#        Enable Enabled Eluna LuaEngine
  3839. +#        Default: 1 (Enabled)
  3840. +#                 0 (Disabled)
  3841. +#
  3842. +#    Eluna.ScriptPath
  3843. +#        Default: "lua_scripts"
  3844. +#
  3845. +###################################################################################################################
  3846. +
  3847. +Eluna.Enabled = 1
  3848. +Eluna.ScriptPath = "lua_scripts"
  3849. diff --git a/src/shared/Common.h b/src/shared/Common.h
  3850. index 0885b1d..0c29af8 100644
  3851. --- a/src/shared/Common.h
  3852. +++ b/src/shared/Common.h
  3853. @@ -242,6 +242,7 @@ enum LocaleConstant
  3854.  };
  3855.  
  3856.  #define MAX_LOCALE 9
  3857. +#define DEFAULT_LOCALE LOCALE_enUS
  3858.  
  3859.  /**
  3860.   * @brief
  3861. @@ -251,6 +252,8 @@ enum LocaleConstant
  3862.   */
  3863.  LocaleConstant GetLocaleByName(const std::string& name);
  3864.  
  3865. +typedef std::vector<std::string> StringVector;
  3866. +
  3867.  extern char const* localeNames[MAX_LOCALE]; /**< TODO */
  3868.  
  3869.  /**
  3870. diff --git a/src/shared/Database/DBCStore.h b/src/shared/Database/DBCStore.h
  3871. index 1aae802..b111f17 100644
  3872. --- a/src/shared/Database/DBCStore.h
  3873. +++ b/src/shared/Database/DBCStore.h
  3874. @@ -55,13 +55,24 @@ class DBCStorage
  3875.           * @param id
  3876.           * @return const T
  3877.           */
  3878. -        T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable[id]; }
  3879. +        //T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable[id]; }
  3880. +        T const* LookupEntry(uint32 id) const
  3881. +        {
  3882. +            if (loaded)
  3883. +            {
  3884. +                typename std::map<uint32, T const*>::const_iterator it = data.find(id);
  3885. +                if (it != data.end())
  3886. +                    return it->second;
  3887. +            }
  3888. +            return (id >= nCount) ? NULL : indexTable[id];
  3889. +        }
  3890.          /**
  3891.           * @brief
  3892.           *
  3893.           * @return uint32
  3894.           */
  3895. -        uint32  GetNumRows() const { return nCount; }
  3896. +        //uint32  GetNumRows() const { return nCount; }
  3897. +        uint32 GetNumRows() const { return loaded ? data.size() : nCount; }
  3898.          /**
  3899.           * @brief
  3900.           *
  3901. @@ -99,6 +110,22 @@ class DBCStorage
  3902.              // error in dbc file at loading if NULL
  3903.              return indexTable != NULL;
  3904.          }
  3905. +        
  3906. +        void SetEntry(uint32 id, T* t) // Cryptic they say..
  3907. +        {
  3908. +            if (!loaded)
  3909. +            {
  3910. +                for (uint32 i = 0; i < nCount; ++i)
  3911. +                {
  3912. +                    T const* node = LookupEntry(i);
  3913. +                    if (!node)
  3914. +                        continue;
  3915. +                    data[i] = node;
  3916. +                }
  3917. +                loaded = true;
  3918. +            }
  3919. +            data[id] = t;
  3920. +        }
  3921.  
  3922.          /**
  3923.           * @brief
  3924. @@ -129,6 +156,12 @@ class DBCStorage
  3925.           */
  3926.          void Clear()
  3927.          {
  3928. +            if (loaded)
  3929. +            {
  3930. +                data.clear();
  3931. +                loaded = false;
  3932. +            }
  3933. +            
  3934.              if (!indexTable)
  3935.                  { return; }
  3936.  
  3937. @@ -165,6 +198,8 @@ class DBCStorage
  3938.          char const* fmt; /**< TODO */
  3939.          T** indexTable; /**< TODO */
  3940.          T* m_dataTable; /**< TODO */
  3941. +        std::map<uint32, T const*> data;
  3942. +        bool loaded;
  3943.          StringPoolList m_stringPoolList; /**< TODO */
  3944.  };
  3945.  
  3946. diff --git a/src/shared/Database/Field.h b/src/shared/Database/Field.h
  3947. index 6c841eb..2714b76 100644
  3948. --- a/src/shared/Database/Field.h
  3949. +++ b/src/shared/Database/Field.h
  3950. @@ -104,6 +104,8 @@ class Field
  3951.           * @return bool
  3952.           */
  3953.          bool GetBool() const { return mValue ? atoi(mValue) > 0 : false; }
  3954. +        double GetDouble() const { return mValue ? static_cast<double>(atof(mValue)) : 0.0f; }
  3955. +        int8 GetInt8() const { return mValue ? static_cast<int8>(atol(mValue)) : int8(0); }
  3956.          /**
  3957.           * @brief
  3958.           *
  3959. @@ -147,6 +149,15 @@ class Field
  3960.  
  3961.              return value;
  3962.          }
  3963. +        
  3964. +        int64 GetInt64() const
  3965. +        {
  3966. +            int64 value = 0;
  3967. +            if (!mValue || sscanf(mValue, SI64FMTD, &value) == -1)
  3968. +                return 0;
  3969. +            
  3970. +            return value;
  3971. +        }
  3972.  
  3973.          /**
  3974.           * @brief
  3975. diff --git a/src/shared/Log.cpp b/src/shared/Log.cpp
  3976. index 1eb04b7..e547471 100644
  3977. --- a/src/shared/Log.cpp
  3978. +++ b/src/shared/Log.cpp
  3979. @@ -71,7 +71,7 @@ const int LogType_count = int(LogError) + 1;
  3980.  
  3981.  Log::Log() :
  3982.      raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
  3983. -    dberLogfile(NULL), eventAiErLogfile(NULL), scriptErrLogFile(NULL), worldLogfile(NULL), m_colored(false), m_includeTime(false), m_gmlog_per_account(false), m_scriptLibName(NULL)
  3984. +    dberLogfile(NULL), elunaErrLogfile(NULL), eventAiErLogfile(NULL), scriptErrLogFile(NULL), worldLogfile(NULL), m_colored(false), m_includeTime(false), m_gmlog_per_account(false), m_scriptLibName(NULL)
  3985.  {
  3986.      Initialize();
  3987.  }
  3988. @@ -267,6 +267,7 @@ void Log::Initialize()
  3989.  
  3990.      charLogfile = openLogFile("CharLogFile", "CharLogTimestamp", "a");
  3991.      dberLogfile = openLogFile("DBErrorLogFile", NULL, "a");
  3992. +    elunaErrLogfile = openLogFile("ElunaErrorLogFile", NULL, "a");
  3993.      eventAiErLogfile = openLogFile("EventAIErrorLogFile", NULL, "a");
  3994.      raLogfile = openLogFile("RaLogFile", NULL, "a");
  3995.      worldLogfile = openLogFile("WorldLogFile", "WorldLogTimestamp", "a");
  3996. @@ -520,6 +521,81 @@ void Log::outErrorDb(const char* err, ...)
  3997.      fflush(stderr);
  3998.  }
  3999.  
  4000. +void Log::outErrorEluna()
  4001. +{
  4002. +    if (m_includeTime)
  4003. +        outTime();
  4004. +    
  4005. +    fprintf(stderr, "\n");
  4006. +    
  4007. +    if (logfile)
  4008. +    {
  4009. +        outTimestamp(logfile);
  4010. +        fprintf(logfile, "ERROR Eluna\n");
  4011. +        fflush(logfile);
  4012. +    }
  4013. +    
  4014. +    if (elunaErrLogfile)
  4015. +    {
  4016. +        outTimestamp(elunaErrLogfile);
  4017. +        fprintf(elunaErrLogfile, "\n");
  4018. +        fflush(elunaErrLogfile);
  4019. +    }
  4020. +    
  4021. +    fflush(stderr);
  4022. +}
  4023. +
  4024. +void Log::outErrorEluna(const char* err, ...)
  4025. +{
  4026. +    if (!err)
  4027. +        return;
  4028. +    
  4029. +    if (m_colored)
  4030. +        SetColor(false, m_colors[LogError]);
  4031. +    
  4032. +    if (m_includeTime)
  4033. +        outTime();
  4034. +    
  4035. +    va_list ap;
  4036. +    
  4037. +    va_start(ap, err);
  4038. +    vutf8printf(stderr, err, &ap);
  4039. +    va_end(ap);
  4040. +    
  4041. +    if (m_colored)
  4042. +        ResetColor(false);
  4043. +    
  4044. +    fprintf(stderr, "\n");
  4045. +    
  4046. +    if (logfile)
  4047. +    {
  4048. +        outTimestamp(logfile);
  4049. +        fprintf(logfile, "ERROR Eluna: ");
  4050. +        
  4051. +        va_start(ap, err);
  4052. +        vfprintf(logfile, err, ap);
  4053. +        va_end(ap);
  4054. +        
  4055. +        fprintf(logfile, "\n");
  4056. +        fflush(logfile);
  4057. +    }
  4058. +    
  4059. +    if (elunaErrLogfile)
  4060. +    {
  4061. +        outTimestamp(elunaErrLogfile);
  4062. +        
  4063. +        va_list ap;
  4064. +        va_start(ap, err);
  4065. +        vfprintf(elunaErrLogfile, err, ap);
  4066. +        va_end(ap);
  4067. +        
  4068. +        fprintf(elunaErrLogfile, "\n");
  4069. +        fflush(elunaErrLogfile);
  4070. +    }
  4071. +    
  4072. +    fflush(stderr);
  4073. +}
  4074. +
  4075.  void Log::outErrorEventAI()
  4076.  {
  4077.      if (m_includeTime)
  4078. diff --git a/src/shared/Log.h b/src/shared/Log.h
  4079. index 0c809de..04717bc 100644
  4080. --- a/src/shared/Log.h
  4081. +++ b/src/shared/Log.h
  4082. @@ -142,6 +142,10 @@ class Log : public MaNGOS::Singleton<Log, MaNGOS::ClassLevelLockable<Log, ACE_Th
  4083.              if (dberLogfile != NULL)
  4084.                  { fclose(dberLogfile); }
  4085.              dberLogfile = NULL;
  4086. +            
  4087. +            if (elunaErrLogfile != NULL)
  4088. +                fclose(elunaErrLogfile);
  4089. +            elunaErrLogfile = NULL;
  4090.  
  4091.              if (eventAiErLogfile != NULL)
  4092.                  { fclose(eventAiErLogfile); }
  4093. @@ -233,6 +237,17 @@ class Log : public MaNGOS::Singleton<Log, MaNGOS::ClassLevelLockable<Log, ACE_Th
  4094.          void outChar(const char* str, ...)        ATTR_PRINTF(2, 3);
  4095.          /**
  4096.           * @brief any log level
  4097. +         *
  4098. +         */
  4099. +        void outErrorEluna();
  4100. +        /**
  4101. +         * @brief any log level
  4102. +         *
  4103. +         * @param str...
  4104. +         */
  4105. +        void outErrorEluna(const char* str, ...)        ATTR_PRINTF(2, 3);
  4106. +        /**
  4107. +         * @brief any log level
  4108.           *
  4109.           */
  4110.          void outErrorEventAI();
  4111. @@ -399,6 +414,7 @@ class Log : public MaNGOS::Singleton<Log, MaNGOS::ClassLevelLockable<Log, ACE_Th
  4112.          FILE* gmLogfile; /**< TODO */
  4113.          FILE* charLogfile; /**< TODO */
  4114.          FILE* dberLogfile; /**< TODO */
  4115. +        FILE* elunaErrLogfile; /**< TODO */
  4116.          FILE* eventAiErLogfile; /**< TODO */
  4117.          FILE* scriptErrLogFile; /**< TODO */
  4118.          FILE* worldLogfile; /**< TODO */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement