diff --git a/CMakeLists.txt b/CMakeLists.txt index 32edeb345..35385f227 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,27 @@ if(EXISTS "conf/config.cmake") include(conf/config.cmake) endif() +# +# Loading dyn modules +# + +# add modules and dependencies +CU_SUBDIRLIST(sub_DIRS "${CMAKE_SOURCE_DIR}/modules" FALSE FALSE) +FOREACH(subdir ${sub_DIRS}) + + get_filename_component(MODULENAME ${subdir} NAME) + + if (";${DISABLED_AC_MODULES};" MATCHES ";${MODULENAME};") + continue() + endif() + + STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" subdir_rel ${subdir}) + if(EXISTS "${subdir}/CMakeLists.txt") + message("Loading module: ${subdir_rel}") + add_subdirectory("${subdir_rel}") + endif() +ENDFOREACH() + CU_RUN_HOOK("AFTER_LOAD_CONF") # build in Release-mode by default if not explicitly set @@ -107,26 +128,6 @@ if( TOOLS ) add_subdirectory(src/tools) endif() -# -# Loading dyn modules -# - -# add modules and dependencies -CU_SUBDIRLIST(sub_DIRS "${CMAKE_SOURCE_DIR}/modules" FALSE FALSE) -FOREACH(subdir ${sub_DIRS}) - - get_filename_component(MODULENAME ${subdir} NAME) - - if (";${DISABLED_AC_MODULES};" MATCHES ";${MODULENAME};") - continue() - endif() - - STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" subdir_rel ${subdir}) - if(EXISTS "${subdir}/CMakeLists.txt") - message("Loading module: ${subdir_rel}") - add_subdirectory("${subdir_rel}") - endif() -ENDFOREACH() # # Loading application sources diff --git a/src/common/DataStores/DBCStore.h b/src/common/DataStores/DBCStore.h index 9948767a6..a17656798 100644 --- a/src/common/DataStores/DBCStore.h +++ b/src/common/DataStores/DBCStore.h @@ -59,7 +59,11 @@ class DBCStorage typedef std::list StringPoolList; public: explicit DBCStorage(char const* f) +#ifndef ELUNA : fmt(f), nCount(0), fieldCount(0), dataTable(NULL) +#else + : fmt(f), nCount(0), fieldCount(0), dataTable(NULL), maxdatacount(0), mindatacount(std::numeric_limits::max()) +#endif { indexTable.asT = NULL; } @@ -68,10 +72,32 @@ class DBCStorage T const* LookupEntry(uint32 id) const { +#ifdef ELUNA + if (id <= maxdatacount && id >= mindatacount) + { + typename std::unordered_map::const_iterator it = data.find(id); + if (it != data.end()) + return it->second; + } +#endif return (id >= nCount) ? NULL : indexTable.asT[id]; } +#ifdef ELUNA + void SetEntry(uint32 id, T* t) + { + delete data[id]; + data[id] = t; + maxdatacount = std::max(maxdatacount, id); + mindatacount = std::min(mindatacount, id); + } +#endif + +#ifndef ELUNA uint32 GetNumRows() const { return nCount; } +#else + uint32 GetNumRows() const { return std::max(maxdatacount + 1, nCount); } +#endif char const* GetFormat() const { return fmt; } uint32 GetFieldCount() const { return fieldCount; } @@ -248,6 +274,11 @@ class DBCStorage void Clear() { +#ifdef ELUNA + data.clear(); + maxdatacount = 0; + mindatacount = std::numeric_limits::max(); +#endif if (!indexTable.asT) return; @@ -279,6 +310,12 @@ class DBCStorage T* dataTable; StringPoolList stringPoolList; + +#ifdef ELUNA + uint32 maxdatacount; + uint32 mindatacount; + std::unordered_map data; +#endif }; #endif diff --git a/src/common/Database/Field.h b/src/common/Database/Field.h index 6ba3c9e92..4fb665e8c 100644 --- a/src/common/Database/Field.h +++ b/src/common/Database/Field.h @@ -61,6 +61,13 @@ class Field return static_cast(atol((char*)data.value)); } +#ifdef ELUNA + enum_field_types GetType() const + { + return data.type; + } +#endif + uint16 GetUInt16() const { if (!data.value) diff --git a/src/common/Database/QueryResult.cpp b/src/common/Database/QueryResult.cpp index 47457e7f8..3c4c7a739 100644 --- a/src/common/Database/QueryResult.cpp +++ b/src/common/Database/QueryResult.cpp @@ -185,6 +185,14 @@ bool PreparedResultSet::_NextRow() return retval; } +#ifdef ELUNA +char* ResultSet::GetFieldName(uint32 index) const +{ + ASSERT(index < _fieldCount); + return _fields[index].name; +} +#endif + void ResultSet::CleanUp() { if (_currentRow) diff --git a/src/common/Database/QueryResult.h b/src/common/Database/QueryResult.h index f5e8bffb0..0f78be1ef 100644 --- a/src/common/Database/QueryResult.h +++ b/src/common/Database/QueryResult.h @@ -27,7 +27,9 @@ class ResultSet bool NextRow(); uint64 GetRowCount() const { return _rowCount; } uint32 GetFieldCount() const { return _fieldCount; } - +#ifdef ELUNA + char* GetFieldName(uint32 index) const; +#endif Field* Fetch() const { return _currentRow; } const Field & operator [] (uint32 index) const { diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index a0d39c8d6..688b58ab9 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2 * Copyright (C) 2008-2016 TrinityCore * Copyright (C) 2005-2009 MaNGOS diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 469c68e73..768a4143e 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -32,7 +32,9 @@ #include "BattlegroundRV.h" #include "Transport.h" #include "ScriptMgr.h" - +#ifdef ELUNA +#include "LuaEngine.h" +#endif namespace Trinity { class BattlegroundChatBuilder @@ -201,6 +203,10 @@ Battleground::~Battleground() for (uint32 i = 0; i < size; ++i) DelObject(i); +#ifdef ELUNA + sEluna->OnBGDestroy(this, GetBgTypeID(), GetInstanceID()); +#endif + sBattlegroundMgr->RemoveBattleground(GetBgTypeID(), GetInstanceID()); // unload map if (m_Map) @@ -493,6 +499,10 @@ inline void Battleground::_ProcessJoin(uint32 diff) StartingEventOpenDoors(); +#ifdef ELUNA + sEluna->OnBGStart(this, GetBgTypeID(), GetInstanceID()); +#endif + SendWarningToAll(StartMessageIds[BG_STARTING_EVENT_FOURTH]); SetStatus(STATUS_IN_PROGRESS); SetStartDelayTime(StartDelayTimes[BG_STARTING_EVENT_FOURTH]); @@ -1037,6 +1047,10 @@ void Battleground::EndBattleground(TeamId winnerTeamId) if (winmsg_id) SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL); + +#ifdef ELUNA + sEluna->OnBGEnd(this, GetBgTypeID(), GetInstanceID(), winnerTeamId); +#endif } uint32 Battleground::GetBonusHonorFromKill(uint32 kills) const diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 130ca2678..fdbbcf4c5 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -34,6 +34,9 @@ #include "DisableMgr.h" #include "Opcodes.h" #include "BattlegroundQueue.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif /*********************************************************/ /*** BATTLEGROUND MANAGER ***/ @@ -1003,6 +1006,9 @@ void BattlegroundMgr::AddBattleground(Battleground* bg) m_BattlegroundTemplates[bg->GetBgTypeID()] = bg; else m_Battlegrounds[bg->GetInstanceID()] = bg; +#ifdef ELUNA + sEluna->OnBGCreate(bg, bg->GetBgTypeID(), bg->GetInstanceID()); +#endif } void BattlegroundMgr::RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 instanceId) diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 2af79f869..944a72ad0 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -24,6 +24,10 @@ #include "ScriptMgr.h" #include "ChatLink.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + bool ChatHandler::load_command_table = true; std::vector const& ChatHandler::getCommandTable() @@ -272,6 +276,10 @@ bool ChatHandler::ExecuteCommandInTable(std::vector const& table, c { if (!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd.c_str())) { +#ifdef ELUNA + if (!sEluna->OnCommand(GetSession() ? GetSession()->GetPlayer() : NULL, oldtext)) + return true; +#endif if (text[0] != '\0') SendSysMessage(LANG_NO_SUBCMD); else @@ -421,6 +429,10 @@ bool ChatHandler::ParseCommands(char const* text) if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) { +#ifdef ELUNA + if (!sEluna->OnCommand(GetSession() ? GetSession()->GetPlayer() : NULL, text)) + return true; +#endif if (m_session && AccountMgr::IsPlayerAccount(m_session->GetSecurity())) return false; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index e7a4be7c1..c0a2f98eb 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -646,7 +646,7 @@ struct ChrClassesEntry // 1, unused uint32 powerType; // 2 // 3-4, unused - //char* name[16]; // 5-20 unused + char* name[16]; // 5-20 unused // 21 string flag, unused //char* nameFemale[16]; // 21-36 unused, if different from base (male) case // 37 string flag, unused diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 52a781176..d5441bcdd 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -22,7 +22,7 @@ char const BattlemasterListEntryfmt[] = "niiiiiiiiixssssssssssssssssxiixx"; char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; char const CharTitlesEntryfmt[] = "nxssssssssssssssssxssssssssssssssssxi"; char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) -char const ChrClassesEntryfmt[] = "nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; +char const ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii"; char const ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx"; char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxx"; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 759c6dfcf..54d83e9b7 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -42,6 +42,10 @@ #include "Transport.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const { TrainerSpellMap::const_iterator itr = spellList.find(spell_id); @@ -211,6 +215,9 @@ void Creature::AddToWorld() AIM_Initialize(); if (IsVehicle()) GetVehicleKit()->Install(); +#ifdef ELUNA + sEluna->OnAddToWorld(this); +#endif } } @@ -218,6 +225,9 @@ void Creature::RemoveFromWorld() { if (IsInWorld()) { +#ifdef ELUNA + sEluna->OnRemoveFromWorld(this); +#endif if (GetZoneScript()) GetZoneScript()->OnCreatureRemove(this); if (m_formation) diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index dc3d0cbbb..84faf10dd 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -1,4 +1,4 @@ -/* +/* licenzastrasd1 licenzastrasd2 licenzastrasd3 diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index ff7143db3..102986cc1 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -25,6 +25,10 @@ #include "Transport.h" #include "AccountMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + GameObject::GameObject() : WorldObject(false), MovableMapObject(), m_model(NULL), m_goValue(), m_AI(NULL) { @@ -147,6 +151,9 @@ void GameObject::AddToWorld() EnableCollision(GetGoState() == GO_STATE_READY || IsTransport()); // pussywizard: this startOpen is unneeded here, collision depends entirely on GOState WorldObject::AddToWorld(); +#ifdef ELUNA + sEluna->OnAddToWorld(this); +#endif } } @@ -155,6 +162,9 @@ void GameObject::RemoveFromWorld() ///- Remove the gameobject from the accessor if (IsInWorld()) { +#ifdef ELUNA + sEluna->OnRemoveFromWorld(this); +#endif if (m_zoneScript) m_zoneScript->OnGameObjectRemove(this); @@ -328,7 +338,10 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa } void GameObject::Update(uint32 diff) -{ +{ +#ifdef ELUNA + sEluna->UpdateAI(this, diff); +#endif if (AI()) AI()->UpdateAI(diff); else if (!AIM_Initialize()) @@ -1225,6 +1238,10 @@ void GameObject::Use(Unit* user) if (Player* playerUser = user->ToPlayer()) { +#ifdef ELUNA + if (sEluna->OnGossipHello(playerUser, this)) + return; +#endif if (sScriptMgr->OnGossipHello(playerUser, this)) return; @@ -2036,6 +2053,9 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* break; case GO_DESTRUCTIBLE_DAMAGED: { +#ifdef ELUNA + sEluna->OnDamaged(this, eventInvoker); +#endif EventInform(m_goInfo->building.damagedEvent); sScriptMgr->OnGameObjectDamaged(this, eventInvoker); if (BattlegroundMap* bgMap = GetMap()->ToBattlegroundMap()) @@ -2064,6 +2084,9 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* } case GO_DESTRUCTIBLE_DESTROYED: { +#ifdef ELUNA + sEluna->OnDestroyed(this, eventInvoker); +#endif sScriptMgr->OnGameObjectDestroyed(this, eventInvoker); EventInform(m_goInfo->building.destroyedEvent); if (BattlegroundMap* bgMap = GetMap()->ToBattlegroundMap()) @@ -2118,6 +2141,9 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; +#ifdef ELUNA + sEluna->OnLootStateChanged(this, state); +#endif AI()->OnStateChanged(state, unit); sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); // pussywizard: lootState has nothing to do with collision, it depends entirely on GOState. Loot state is for timed close/open door and respawning, which then sets GOState @@ -2140,6 +2166,9 @@ void GameObject::SetLootState(LootState state, Unit* unit) void GameObject::SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); +#ifdef ELUNA + sEluna->OnGameObjectStateChanged(this, state); +#endif sScriptMgr->OnGameObjectStateChanged(this, state); if (m_model) { diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index f3b4c2ed3..98cac7cd9 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -41,6 +41,11 @@ #include "Chat.h" #include "DynamicVisibility.h" +#ifdef ELUNA +#include "LuaEngine.h" +#include "ElunaEventMgr.h" +#endif + uint32 GuidHigh2TypeId(uint32 guid_hi) { switch (guid_hi) @@ -78,6 +83,11 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1) WorldObject::~WorldObject() { +#ifdef ELUNA + delete elunaEvents; + elunaEvents = NULL; +#endif + // this may happen because there are many !create/delete if (IsWorldObject() && m_currMap) { @@ -957,6 +967,9 @@ void MovementInfo::OutDebug() } WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0), +#ifdef ELUNA +elunaEvents(NULL), +#endif m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL), m_transport(NULL), m_currMap(NULL), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0) @@ -965,6 +978,13 @@ m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0) m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); } +#ifdef ELUNA +void WorldObject::Update(uint32 time_diff) +{ + elunaEvents->Update(time_diff); +} +#endif + void WorldObject::SetWorldObject(bool on) { if (!IsInWorld()) @@ -1990,6 +2010,13 @@ void WorldObject::SetMap(Map* map) m_currMap = map; m_mapId = map->GetId(); m_InstanceId = map->GetInstanceId(); + +#ifdef ELUNA + delete elunaEvents; + // On multithread replace this with a pointer to map's Eluna pointer stored in a map + elunaEvents = new ElunaEventProcessor(&Eluna::GEluna, this); +#endif + if (IsWorldObject()) m_currMap->AddWorldObject(this); } @@ -2000,6 +2027,12 @@ void WorldObject::ResetMap() ASSERT(!IsInWorld()); if (IsWorldObject()) m_currMap->RemoveWorldObject(this); + +#ifdef ELUNA + delete elunaEvents; + elunaEvents = NULL; +#endif + m_currMap = NULL; //maybe not for corpse //m_mapId = 0; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index b8a62b6f9..4273d173f 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -16,6 +16,10 @@ #include "GridDefines.h" #include "Map.h" +#ifdef ELUNA +class ElunaEventProcessor; +#endif + #include #include #include @@ -721,8 +725,11 @@ class WorldObject : public Object, public WorldLocation public: virtual ~WorldObject(); - virtual void Update (uint32 /*time_diff*/) { } - +#ifdef ELUNA + virtual void Update(uint32 /*time_diff*/); +#else + virtual void Update(uint32 /*time_diff*/) { }; +#endif void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask); virtual void RemoveFromWorld() @@ -735,6 +742,10 @@ class WorldObject : public Object, public WorldLocation Object::RemoveFromWorld(); } +#ifdef ELUNA + ElunaEventProcessor* elunaEvents; +#endif + void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const; void GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const; bool GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0, const WorldObject* forWho = NULL, bool force = false) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index cdee6659b..b740c68ce 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -75,6 +75,10 @@ #include "TicketMgr.h" #include "ScriptMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + #define ZONE_UPDATE_INTERVAL (2*IN_MILLISECONDS) #define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3)) @@ -5223,6 +5227,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) // update visibility UpdateObjectVisibility(); +#ifdef ELUNA + sEluna->OnResurrect(this); +#endif + if(!applySickness) return; @@ -12337,7 +12345,11 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const return EQUIP_ERR_OK; } - +#ifdef ELUNA + InventoryResult eres = sEluna->OnCanUseItem(this, proto->ItemId); + if (eres != EQUIP_ERR_OK) + return eres; +#endif return EQUIP_ERR_ITEM_NOT_FOUND; } @@ -12783,7 +12795,9 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) pItem2->SetState(ITEM_CHANGED, this); ApplyEquipCooldown(pItem2); - +#ifdef ELUNA + sEluna->OnEquip(this, pItem2, bag, slot); +#endif return pItem2; } @@ -12791,6 +12805,10 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); +#ifdef ELUNA + sEluna->OnEquip(this, pItem, bag, slot); +#endif + sScriptMgr->OnEquip(this, pItem, bag, slot, update); return pItem; } @@ -12813,6 +12831,10 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM, pItem->GetEntry()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); + +#ifdef ELUNA + sEluna->OnEquip(this, pItem, (pos >> 8), slot); +#endif } } @@ -13027,6 +13049,8 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); + sScriptMgr->OnItemRemove(this, pItem); + if (bag == INVENTORY_SLOT_BAG_0) { SetUInt64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2), 0); @@ -15529,6 +15553,9 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver) switch (questGiver->GetTypeId()) { case TYPEID_UNIT: +#ifdef ELUNA + sEluna->OnQuestAccept(this, questGiver->ToCreature(), quest); +#endif sScriptMgr->OnQuestAccept(this, (questGiver->ToCreature()), quest); questGiver->ToCreature()->AI()->sQuestAccept(this, quest); break; @@ -15555,6 +15582,9 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver) break; } case TYPEID_GAMEOBJECT: +#ifdef ELUNA + sEluna->OnQuestAccept(this, questGiver->ToGameObject(), quest); +#endif sScriptMgr->OnQuestAccept(this, questGiver->ToGameObject(), quest); questGiver->ToGameObject()->AI()->QuestAccept(this, quest); break; @@ -16615,6 +16645,9 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) { case TYPEID_GAMEOBJECT: { +#ifdef ELUNA + sEluna->GetDialogStatus(this, questgiver->ToGameObject()); +#endif QuestGiverStatus questStatus = QuestGiverStatus(sScriptMgr->GetDialogStatus(this, questgiver->ToGameObject())); if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS) return questStatus; @@ -16624,6 +16657,9 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) } case TYPEID_UNIT: { +#ifdef ELUNA + sEluna->GetDialogStatus(this, questgiver->ToCreature()); +#endif QuestGiverStatus questStatus = QuestGiverStatus(sScriptMgr->GetDialogStatus(this, questgiver->ToCreature())); if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS) return questStatus; @@ -19548,6 +19584,9 @@ void Player::SaveToDB(bool create, bool logout) #endif outDebugValues(); + if (!create) + sScriptMgr->OnPlayerSave(this); + SQLTransaction trans = CharacterDatabase.BeginTransaction(); _SaveCharacter(create, trans); @@ -20751,6 +20790,10 @@ void Player::Say(const std::string& text, const uint32 language) { std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text); +#ifdef ELUNA + if (!sEluna->OnChat(this, CHAT_MSG_SAY, language, _text)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, Language(language), this, this, _text); @@ -20761,6 +20804,10 @@ void Player::Yell(const std::string& text, const uint32 language) { std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text); +#ifdef ELUNA + if (!sEluna->OnChat(this, CHAT_MSG_YELL, language, _text)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, Language(language), this, this, _text); @@ -20771,7 +20818,10 @@ void Player::TextEmote(const std::string& text) { std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text); - +#ifdef ELUNA + if (!sEluna->OnChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT)); @@ -20788,6 +20838,10 @@ void Player::Whisper(const std::string& text, uint32 language, uint64 receiver) std::string _text(text); sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, rPlayer); +#ifdef ELUNA + if (!sEluna->OnChat(this, CHAT_MSG_WHISPER, language, _text, rPlayer)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text); @@ -25099,6 +25153,9 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) if (loot->containerId > 0) sLootItemStorage->RemoveStoredLootItem(loot->containerId, item->itemid, item->count, loot); +#ifdef ELUNA + sEluna->OnLootItem(this, newitem, item->count, this->GetLootGUID()); +#endif sScriptMgr->OnLootItem(this, newitem, item->count, this->GetLootGUID()); } else @@ -25538,6 +25595,10 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) // xinef: update free talent points count m_usedTalentCount += talentPointsChange; SetFreeTalentPoints(CurTalentPoints - talentPointsChange); + +#ifdef ELUNA + sEluna->OnLearnTalents(this, talentId, talentRank, spellId); +#endif } void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 680ce345d..ea10497c3 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -53,6 +53,11 @@ #include "DynamicVisibility.h" #include "AccountMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#include "ElunaEventMgr.h" +#endif + #include float baseMoveSpeed[MAX_MOVE_TYPE] = @@ -335,6 +340,9 @@ Unit::~Unit() void Unit::Update(uint32 p_time) { +#ifdef ELUNA + elunaEvents->Update(p_time); +#endif // WARNING! Order of execution here is important, do not change. // Spells must be processed with event system BEFORE they go to _UpdateSpells. // Or else we may have some SPELL_STATE_FINISHED spells stalled in pointers, that is bad. @@ -12552,6 +12560,10 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy, uint32 duration) controlled->SetInCombatState(PvP, enemy); } +#ifdef ELUNA + if (Player* player = this->ToPlayer()) + sEluna->OnPlayerEnterCombat(player, enemy); +#endif } void Unit::ClearInCombat() @@ -12580,6 +12592,10 @@ void Unit::ClearInCombat() for (uint8 i = 0; i < MAX_RUNES; ++i) player->SetGracePeriod(i, 0); } +#ifdef ELUNA + if (Player* player = this->ToPlayer()) + sEluna->OnPlayerLeaveCombat(player); +#endif } void Unit::ClearInPetCombat() diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 0cc32f6ae..d9eba8a70 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -18,7 +18,9 @@ #include "UnitAI.h" #include "GameObjectAI.h" #include "Transport.h" - +#ifdef ELUNA +#include "LuaEngine.h" +#endif #include bool GameEventMgr::CheckOneGameEvent(uint16 entry) const @@ -125,6 +127,10 @@ bool GameEventMgr::StartEvent(uint16 event_id, bool overwrite) if (data.end <= data.start) data.end = data.start + data.length; } +#ifdef ELUNA + if (IsActiveEvent(event_id)) + sEluna->OnGameEventStart(event_id); +#endif return false; } else @@ -147,7 +153,10 @@ bool GameEventMgr::StartEvent(uint16 event_id, bool overwrite) // or to scedule another update where the next event will be started if (overwrite && conditions_met) sWorld->ForceGameEventUpdate(); - +#ifdef ELUNA + if (IsActiveEvent(event_id)) + sEluna->OnGameEventStart(event_id); +#endif return conditions_met; } } @@ -190,6 +199,10 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite) CharacterDatabase.CommitTransaction(trans); } } +#ifdef ELUNA + if (!IsActiveEvent(event_id)) + sEluna->OnGameEventStop(event_id); +#endif } void GameEventMgr::LoadFromDB() diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 64330989c..126b4b8ac 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -5678,7 +5678,11 @@ uint32 ObjectMgr::GetNearestTaxiNode(float x, float y, float z, uint32 mapid, ui uint32 submask = 1<<((i-1)%32); // skip not taxi network nodes +#ifndef ELUNA if ((sTaxiNodesMask[field] & submask) == 0) +#else + if (field >= TaxiMaskSize || (sTaxiNodesMask[field] & submask) == 0) +#endif continue; float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 435d9a1e7..892a72d14 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -38,6 +38,9 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "Transport.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif class LoginQueryHolder : public SQLQueryHolder { diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 3eb6cb906..0b3eafe93 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -28,6 +28,9 @@ #include "Util.h" #include "ScriptMgr.h" #include "AccountMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) { @@ -151,6 +154,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) return; sScriptMgr->OnPlayerChat(sender, type, lang, msg, receiver); +#ifdef ELUNA + if (!sEluna->OnChat(sender, type, lang, msg, receiver)) + return; +#endif } break; @@ -390,7 +397,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); @@ -403,6 +413,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, guild)) + return; +#endif guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } @@ -415,6 +429,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, guild)) + return; +#endif guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } @@ -431,7 +449,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); @@ -448,7 +469,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); @@ -460,7 +484,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group)) + return; +#endif WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); @@ -474,7 +501,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); @@ -487,7 +517,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); - +#ifdef ELUNA + if (!sEluna->OnChat(GetPlayer(), type, lang, msg, group)) + return; +#endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); @@ -509,6 +542,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); +#ifdef ELUNA + if (!sEluna->OnChat(sender, type, lang, msg, chn)) + return; +#endif chn->Say(sender->GetGUID(), msg.c_str(), lang); } } @@ -535,6 +572,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) } sScriptMgr->OnPlayerChat(sender, type, lang, msg); +#ifdef ELUNA + if (!sEluna->OnChat(sender, type, lang, msg)) + return; +#endif } break; } @@ -558,7 +599,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket & recvData) } sScriptMgr->OnPlayerChat(sender, type, lang, msg); - +#ifdef ELUNA + if (!sEluna->OnChat(sender, type, lang, msg)) + return; +#endif break; } default: diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index f255abaeb..06557ba63 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -21,6 +21,10 @@ #include "WorldSession.h" #include "ObjectMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData) { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) @@ -200,7 +204,9 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket & /*recvData*/) data << uint8(1); // "You loot..." SendPacket(&data); } - +#ifdef ELUNA + sEluna->OnLootMoney(player, loot->gold); +#endif loot->gold = 0; // Delete the money loot record from the DB @@ -493,6 +499,10 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) target->SendNewItem(newitem, uint32(item.count), false, false, true); target->UpdateLootAchievements(&item, loot); +#ifdef ELUNA + sEluna->OnLootItem(target, newitem, item.count, lootguid); +#endif + // mark as looted item.count=0; item.is_looted=true; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index fa43f6dbd..ccaacf408 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -43,6 +43,9 @@ #include "AccountMgr.h" #include "Spell.h" #include "WhoListCache.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data) { @@ -71,6 +74,10 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket & recv_data) GetPlayer()->KillPlayer(); } +#ifdef ELUNA + sEluna->OnRepop(GetPlayer()); +#endif + //this is spirit release confirm? GetPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); GetPlayer()->BuildPlayerRepop(); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 68020895a..281896a54 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -20,6 +20,9 @@ #include "BattlegroundAV.h" #include "ScriptMgr.h" #include "GameObjectAI.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket & recvData) { @@ -89,6 +92,11 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recvData) //if (!creature->GetTransport()) // pussywizard: reverted with new spline (old: without this check, npc would stay in place and the transport would continue moving, so the npc falls off. NPCs on transports don't have waypoints, so stopmoving is not needed) creature->StopMoving(); +#ifdef ELUNA + if (sEluna->OnGossipHello(_player, creature)) + return; +#endif + if (sScriptMgr->OnGossipHello(_player, creature)) return; @@ -412,7 +420,9 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) _player->TakeQuestSourceItem(questId, true); // remove quest src item from player _player->RemoveActiveQuest(questId); _player->RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId); - +#ifdef ELUNA + sEluna->OnQuestAbandon(_player, questId); +#endif #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDetail("Player %u abandoned quest %u", _player->GetGUIDLow(), questId); #endif diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index f1947315d..9be74137f 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -22,6 +22,9 @@ #include "GameObjectAI.h" #include "SpellAuraEffects.h" #include "Player.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets) { diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 14b2a512f..efde5585d 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -24,6 +24,9 @@ #include "VMapFactory.h" #include "LFGMgr.h" #include "Chat.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif union u_map_magic { @@ -2695,18 +2698,35 @@ void InstanceMap::CreateInstanceScript(bool load, std::string data, uint32 compl { if (instance_script != NULL) return; +#ifdef ELUNA + bool isElunaAI = false; + instance_script = sEluna->GetInstanceData(this); + if (instance_script) + isElunaAI = true; - InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(GetId()); - if (mInstance) + // if Eluna AI was fetched succesfully we should not call CreateInstanceData nor set the unused scriptID + if (!isElunaAI) { - i_script_id = mInstance->ScriptId; - instance_script = sScriptMgr->CreateInstanceScript(this); +#endif + InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(GetId()); + if (mInstance) + { + i_script_id = mInstance->ScriptId; + instance_script = sScriptMgr->CreateInstanceScript(this); + } +#ifdef ELUNA } +#endif if (!instance_script) return; - instance_script->Initialize(); +#ifdef ELUNA + // use mangos behavior if we are dealing with Eluna AI + // initialize should then be called only if load is false + if (!isElunaAI || !load) +#endif + instance_script->Initialize(); if (load) { diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 24d21f3da..dad9c23a3 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -15,6 +15,10 @@ #include "Group.h" #include "Player.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + MapInstanced::MapInstanced(uint32 id) : Map(id, 0, DUNGEON_DIFFICULTY_NORMAL) { // initialize instanced maps list @@ -254,6 +258,11 @@ bool MapInstanced::DestroyInstance(InstancedMaps::iterator &itr) //if (itr->second->IsBattlegroundOrArena()) // sMapMgr->FreeInstanceId(itr->second->GetInstanceId()); +#ifdef ELUNA + //todo:[ELUNA] I'm not sure this is right. + sEluna->FreeInstanceId(itr->second->GetInstanceId()); +#endif + // erase map delete itr->second; m_InstancedMaps.erase(itr++); @@ -265,4 +274,4 @@ bool MapInstanced::CanEnter(Player* /*player*/, bool /*loginCheck*/) { //ASSERT(false); return true; -} \ No newline at end of file +} diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 595233fd9..7be80cda9 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -27,6 +27,9 @@ #include "LFGMgr.h" #include "Chat.h" #include "AvgDiffTracker.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif MapManager::MapManager() { @@ -42,6 +45,7 @@ MapManager::~MapManager() void MapManager::Initialize() { int num_threads(sWorld->getIntConfig(CONFIG_NUMTHREADS)); + // Start mtmaps if needed. if (num_threads > 0 && m_updater.activate(num_threads) == -1) abort(); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 1925138ab..66981fa3d 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -22,6 +22,11 @@ #include "WorldPacket.h" #include "Chat.h" +#ifdef ELUNA +#include "LuaEngine.h" +#include "ElunaUtility.h" +#endif + // Specialize for each script type class like so: template class ScriptRegistry; template class ScriptRegistry; @@ -442,18 +447,48 @@ void ScriptMgr::OnSocketClose(WorldSocket* socket, bool wasNew) FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket, wasNew); } +void ScriptMgr::OnPacketReceive(WorldSession* session, WorldPacket const& packet) +{ + if (SCR_REG_LST(ServerScript).empty()) + return; + + WorldPacket copy(packet); + FOREACH_SCRIPT(ServerScript)->OnPacketReceive(session, copy); +} + +void ScriptMgr::OnPacketSend(WorldSession* session, WorldPacket const& packet) +{ + ASSERT(session); + + if (SCR_REG_LST(ServerScript).empty()) + return; + + WorldPacket copy(packet); + FOREACH_SCRIPT(ServerScript)->OnPacketSend(session, copy); +} + + void ScriptMgr::OnOpenStateChange(bool open) { +#ifdef ELUNA + sEluna->OnOpenStateChange(open); +#endif FOREACH_SCRIPT(WorldScript)->OnOpenStateChange(open); } void ScriptMgr::OnBeforeConfigLoad(bool reload) { +#ifdef ELUNA + sEluna->OnConfigLoad(reload, true); +#endif FOREACH_SCRIPT(WorldScript)->OnBeforeConfigLoad(reload); } void ScriptMgr::OnAfterConfigLoad(bool reload) { +#ifdef ELUNA + sEluna->OnConfigLoad(reload, false); +#endif FOREACH_SCRIPT(WorldScript)->OnAfterConfigLoad(reload); } @@ -464,16 +499,25 @@ void ScriptMgr::OnMotdChange(std::string& newMotd) void ScriptMgr::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { +#ifdef ELUNA + sEluna->OnShutdownInitiate(code, mask); +#endif FOREACH_SCRIPT(WorldScript)->OnShutdownInitiate(code, mask); } void ScriptMgr::OnShutdownCancel() { +#ifdef ELUNA + sEluna->OnShutdownCancel(); +#endif FOREACH_SCRIPT(WorldScript)->OnShutdownCancel(); } void ScriptMgr::OnWorldUpdate(uint32 diff) { +#ifdef ELUNA + sEluna->OnWorldUpdate(diff); +#endif FOREACH_SCRIPT(WorldScript)->OnUpdate(diff); } @@ -536,6 +580,10 @@ void ScriptMgr::OnCreateMap(Map* map) { ASSERT(map); +#ifdef ELUNA + sEluna->OnCreate(map); +#endif + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnCreate(map); SCR_MAP_END; @@ -553,6 +601,10 @@ void ScriptMgr::OnDestroyMap(Map* map) { ASSERT(map); +#ifdef ELUNA + sEluna->OnDestroy(map); +#endif + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnDestroy(map); SCR_MAP_END; @@ -607,6 +659,11 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) ASSERT(map); ASSERT(player); +#ifdef ELUNA + sEluna->OnMapChanged(player); + sEluna->OnPlayerEnter(map, player); +#endif + FOREACH_SCRIPT(AllMapScript)->OnPlayerEnterAll(map, player); FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player); @@ -628,7 +685,11 @@ void ScriptMgr::OnPlayerLeaveMap(Map* map, Player* player) { ASSERT(map); ASSERT(player); - + +#ifdef ELUNA + sEluna->OnPlayerLeave(map, player); +#endif + FOREACH_SCRIPT(AllMapScript)->OnPlayerLeaveAll(map, player); SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); @@ -648,6 +709,10 @@ void ScriptMgr::OnMapUpdate(Map* map, uint32 diff) { ASSERT(map); +#ifdef ELUNA + sEluna->OnUpdate(map, diff); +#endif + SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); itr->second->OnUpdate(map, diff); SCR_MAP_END; @@ -678,6 +743,11 @@ bool ScriptMgr::OnQuestAccept(Player* player, Item* item, Quest const* quest) ASSERT(item); ASSERT(quest); +#ifdef ELUNA + if (sEluna->OnQuestAccept(player, item, quest)) + return false; +#endif + GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); player->PlayerTalkClass->ClearMenus(); return tmpscript->OnQuestAccept(player, item, quest); @@ -688,6 +758,11 @@ bool ScriptMgr::OnItemUse(Player* player, Item* item, SpellCastTargets const& ta ASSERT(player); ASSERT(item); +#ifdef ELUNA + if (!sEluna->OnUse(player, item, targets)) + return true; +#endif + GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); return tmpscript->OnUse(player, item, targets); } @@ -697,15 +772,35 @@ bool ScriptMgr::OnItemExpire(Player* player, ItemTemplate const* proto) ASSERT(player); ASSERT(proto); +#ifdef ELUNA + if (sEluna->OnExpire(player, proto)) + return false; +#endif + GET_SCRIPT_RET(ItemScript, proto->ScriptId, tmpscript, false); return tmpscript->OnExpire(player, proto); } +bool ScriptMgr::OnItemRemove(Player * player, Item * item) +{ + ASSERT(player); + ASSERT(item); +#ifdef ELUNA + if (sEluna->OnRemove(player, item)) + return false; +#endif + GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); + return tmpscript->OnRemove(player, item); + +} + void ScriptMgr::OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action) { ASSERT(player); ASSERT(item); - +#ifdef ELUNA + sEluna->HandleGossipSelectOption(player, item, sender, action, ""); +#endif GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript); tmpscript->OnGossipSelect(player, item, sender, action); } @@ -714,18 +809,26 @@ void ScriptMgr::OnGossipSelectCode(Player* player, Item* item, uint32 sender, ui { ASSERT(player); ASSERT(item); - +#ifdef ELUNA + sEluna->HandleGossipSelectOption(player, item, sender, action, code); +#endif GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript); tmpscript->OnGossipSelectCode(player, item, sender, action, code); } void ScriptMgr::OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action) { +#ifdef ELUNA + sEluna->HandleGossipSelectOption(player, menu_id, sender, action, ""); +#endif FOREACH_SCRIPT(PlayerScript)->OnGossipSelect(player, menu_id, sender, action); } void ScriptMgr::OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code) { +#ifdef ELUNA + sEluna->HandleGossipSelectOption(player, menu_id, sender, action, code); +#endif FOREACH_SCRIPT(PlayerScript)->OnGossipSelectCode(player, menu_id, sender, action, code); } @@ -733,7 +836,10 @@ bool ScriptMgr::OnGossipHello(Player* player, Creature* creature) { ASSERT(player); ASSERT(creature); - +#ifdef ELUNA + if (sEluna->OnGossipHello(player, creature)) + return true; +#endif GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); player->PlayerTalkClass->ClearMenus(); return tmpscript->OnGossipHello(player, creature); @@ -743,7 +849,10 @@ bool ScriptMgr::OnGossipSelect(Player* player, Creature* creature, uint32 sender { ASSERT(player); ASSERT(creature); - +#ifdef ELUNA + if (sEluna->OnGossipSelect(player, creature, sender, action)) + return true; +#endif GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); return tmpscript->OnGossipSelect(player, creature, sender, action); } @@ -753,7 +862,10 @@ bool ScriptMgr::OnGossipSelectCode(Player* player, Creature* creature, uint32 se ASSERT(player); ASSERT(creature); ASSERT(code); - +#ifdef ELUNA + if (sEluna->OnGossipSelectCode(player, creature, sender, action, code)) + return true; +#endif GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); return tmpscript->OnGossipSelectCode(player, creature, sender, action, code); } @@ -796,7 +908,13 @@ bool ScriptMgr::OnQuestReward(Player* player, Creature* creature, Quest const* q ASSERT(player); ASSERT(creature); ASSERT(quest); - +#ifdef ELUNA + if (sEluna->OnQuestReward(player, creature, quest, opt)) + { + player->PlayerTalkClass->ClearMenus(); + return false; + } +#endif GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, false); player->PlayerTalkClass->ClearMenus(); return tmpscript->OnQuestReward(player, creature, quest, opt); @@ -816,6 +934,11 @@ CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature) { ASSERT(creature); +#ifdef ELUNA + if (CreatureAI* luaAI = sEluna->GetAI(creature)) + return luaAI; +#endif + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, NULL); return tmpscript->GetAI(creature); } @@ -834,7 +957,12 @@ bool ScriptMgr::OnGossipHello(Player* player, GameObject* go) { ASSERT(player); ASSERT(go); - +#ifdef ELUNA + if (sEluna->OnGossipHello(player, go)) + return true; + if (sEluna->OnGameObjectUse(player, go)) + return true; +#endif GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); player->PlayerTalkClass->ClearMenus(); return tmpscript->OnGossipHello(player, go); @@ -844,7 +972,10 @@ bool ScriptMgr::OnGossipSelect(Player* player, GameObject* go, uint32 sender, ui { ASSERT(player); ASSERT(go); - +#ifdef ELUNA + if (sEluna->OnGossipSelect(player, go, sender, action)) + return true; +#endif GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); return tmpscript->OnGossipSelect(player, go, sender, action); } @@ -854,7 +985,10 @@ bool ScriptMgr::OnGossipSelectCode(Player* player, GameObject* go, uint32 sender ASSERT(player); ASSERT(go); ASSERT(code); - +#ifdef ELUNA + if (sEluna->OnGossipSelectCode(player, go, sender, action, code)) + return true; +#endif GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); return tmpscript->OnGossipSelectCode(player, go, sender, action, code); } @@ -875,7 +1009,14 @@ bool ScriptMgr::OnQuestReward(Player* player, GameObject* go, Quest const* quest ASSERT(player); ASSERT(go); ASSERT(quest); - +#ifdef ELUNA + if (sEluna->OnQuestAccept(player, go, quest)) + return false; +#endif +#ifdef ELUNA + if (sEluna->OnQuestReward(player, go, quest, opt)) + return false; +#endif GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, false); player->PlayerTalkClass->ClearMenus(); return tmpscript->OnQuestReward(player, go, quest, opt); @@ -927,6 +1068,10 @@ void ScriptMgr::OnGameObjectUpdate(GameObject* go, uint32 diff) { ASSERT(go); +#ifdef ELUNA + sEluna->UpdateAI(go, diff); +#endif + GET_SCRIPT(GameObjectScript, go->GetScriptId(), tmpscript); tmpscript->OnUpdate(go, diff); } @@ -935,6 +1080,10 @@ GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* go) { ASSERT(go); +#ifdef ELUNA + sEluna->OnSpawn(go); +#endif + GET_SCRIPT_RET(GameObjectScript, go->GetScriptId(), tmpscript, NULL); return tmpscript->GetAI(go); } @@ -943,7 +1092,10 @@ bool ScriptMgr::OnAreaTrigger(Player* player, AreaTrigger const* trigger) { ASSERT(player); ASSERT(trigger); - +#ifdef ELUNA + if (sEluna->OnAreaTrigger(player, trigger)) + return false; +#endif GET_SCRIPT_RET(AreaTriggerScript, sObjectMgr->GetAreaTriggerScriptId(trigger->entry), tmpscript, false); return tmpscript->OnTrigger(player, trigger); } @@ -986,6 +1138,10 @@ void ScriptMgr::OnWeatherChange(Weather* weather, WeatherState state, float grad { ASSERT(weather); +#ifdef ELUNA + sEluna->OnChange(weather, weather->GetZone(), state, grade); +#endif + GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript); tmpscript->OnChange(weather, state, grade); } @@ -1003,6 +1159,10 @@ void ScriptMgr::OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); +#ifdef ELUNA + sEluna->OnAdd(ah, entry); +#endif + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionAdd(ah, entry); } @@ -1011,6 +1171,10 @@ void ScriptMgr::OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); +#ifdef ELUNA + sEluna->OnRemove(ah, entry); +#endif + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionRemove(ah, entry); } @@ -1019,6 +1183,10 @@ void ScriptMgr::OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); +#ifdef ELUNA + sEluna->OnSuccessful(ah, entry); +#endif + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionSuccessful(ah, entry); } @@ -1027,6 +1195,10 @@ void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); +#ifdef ELUNA + sEluna->OnExpire(ah, entry); +#endif + FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry); } @@ -1043,6 +1215,10 @@ void ScriptMgr::OnInstall(Vehicle* veh) ASSERT(veh); ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); +#ifdef ELUNA + sEluna->OnInstall(veh); +#endif + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); tmpscript->OnInstall(veh); } @@ -1052,6 +1228,10 @@ void ScriptMgr::OnUninstall(Vehicle* veh) ASSERT(veh); ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); +#ifdef ELUNA + sEluna->OnUninstall(veh); +#endif + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); tmpscript->OnUninstall(veh); } @@ -1071,6 +1251,10 @@ void ScriptMgr::OnInstallAccessory(Vehicle* veh, Creature* accessory) ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); ASSERT(accessory); +#ifdef ELUNA + sEluna->OnInstallAccessory(veh, accessory); +#endif + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); tmpscript->OnInstallAccessory(veh, accessory); } @@ -1081,6 +1265,10 @@ void ScriptMgr::OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId) ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); ASSERT(passenger); +#ifdef ELUNA + sEluna->OnAddPassenger(veh, passenger, seatId); +#endif + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); tmpscript->OnAddPassenger(veh, passenger, seatId); } @@ -1091,6 +1279,10 @@ void ScriptMgr::OnRemovePassenger(Vehicle* veh, Unit* passenger) ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); ASSERT(passenger); +#ifdef ELUNA + sEluna->OnRemovePassenger(veh, passenger); +#endif + GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); tmpscript->OnRemovePassenger(veh, passenger); } @@ -1146,11 +1338,17 @@ void ScriptMgr::OnRelocate(Transport* transport, uint32 waypointId, uint32 mapId void ScriptMgr::OnStartup() { +#ifdef ELUNA + sEluna->OnStartup(); +#endif FOREACH_SCRIPT(WorldScript)->OnStartup(); } void ScriptMgr::OnShutdown() { +#ifdef ELUNA + sEluna->OnShutdown(); +#endif FOREACH_SCRIPT(WorldScript)->OnShutdown(); } @@ -1171,61 +1369,97 @@ void ScriptMgr::OnPlayerReleasedGhost(Player* player) void ScriptMgr::OnPVPKill(Player* killer, Player* killed) { +#ifdef ELUNA + sEluna->OnPVPKill(killer, killed); +#endif FOREACH_SCRIPT(PlayerScript)->OnPVPKill(killer, killed); } void ScriptMgr::OnCreatureKill(Player* killer, Creature* killed) { +#ifdef ELUNA + sEluna->OnCreatureKill(killer, killed); +#endif FOREACH_SCRIPT(PlayerScript)->OnCreatureKill(killer, killed); } void ScriptMgr::OnPlayerKilledByCreature(Creature* killer, Player* killed) { +#ifdef ELUNA + sEluna->OnPlayerKilledByCreature(killer, killed); +#endif FOREACH_SCRIPT(PlayerScript)->OnPlayerKilledByCreature(killer, killed); } void ScriptMgr::OnPlayerLevelChanged(Player* player, uint8 oldLevel) { +#ifdef ELUNA + sEluna->OnLevelChanged(player, oldLevel); +#endif FOREACH_SCRIPT(PlayerScript)->OnLevelChanged(player, oldLevel); } void ScriptMgr::OnPlayerFreeTalentPointsChanged(Player* player, uint32 points) { +#ifdef ELUNA + sEluna->OnFreeTalentPointsChanged(player, points); +#endif FOREACH_SCRIPT(PlayerScript)->OnFreeTalentPointsChanged(player, points); } void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost) { +#ifdef ELUNA + sEluna->OnTalentsReset(player, noCost); +#endif FOREACH_SCRIPT(PlayerScript)->OnTalentsReset(player, noCost); } void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount) { +#ifdef ELUNA + sEluna->OnMoneyChanged(player, amount); +#endif FOREACH_SCRIPT(PlayerScript)->OnMoneyChanged(player, amount); } void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim) { +#ifdef ELUNA + sEluna->OnGiveXP(player, amount, victim); +#endif FOREACH_SCRIPT(PlayerScript)->OnGiveXP(player, amount, victim); } void ScriptMgr::OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental) { +#ifdef ELUNA + sEluna->OnReputationChange(player, factionID, standing, incremental); +#endif FOREACH_SCRIPT(PlayerScript)->OnReputationChange(player, factionID, standing, incremental); } void ScriptMgr::OnPlayerDuelRequest(Player* target, Player* challenger) { +#ifdef ELUNA + sEluna->OnDuelRequest(target, challenger); +#endif FOREACH_SCRIPT(PlayerScript)->OnDuelRequest(target, challenger); } void ScriptMgr::OnPlayerDuelStart(Player* player1, Player* player2) { +#ifdef ELUNA + sEluna->OnDuelStart(player1, player2); +#endif FOREACH_SCRIPT(PlayerScript)->OnDuelStart(player1, player2); } void ScriptMgr::OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type) { +#ifdef ELUNA + sEluna->OnDuelEnd(winner, loser, type); +#endif FOREACH_SCRIPT(PlayerScript)->OnDuelEnd(winner, loser, type); } @@ -1256,16 +1490,25 @@ void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::stri void ScriptMgr::OnPlayerEmote(Player* player, uint32 emote) { +#ifdef ELUNA + sEluna->OnEmote(player, emote); +#endif FOREACH_SCRIPT(PlayerScript)->OnEmote(player, emote); } void ScriptMgr::OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, uint64 guid) { +#ifdef ELUNA + sEluna->OnTextEmote(player, textEmote, emoteNum, guid); +#endif FOREACH_SCRIPT(PlayerScript)->OnTextEmote(player, textEmote, emoteNum, guid); } void ScriptMgr::OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck) { +#ifdef ELUNA + sEluna->OnSpellCast(player, spell, skipCheck); +#endif FOREACH_SCRIPT(PlayerScript)->OnSpellCast(player, spell, skipCheck); } @@ -1276,6 +1519,9 @@ void ScriptMgr::OnBeforePlayerUpdate(Player* player, uint32 p_time) void ScriptMgr::OnPlayerLogin(Player* player) { +#ifdef ELUNA + sEluna->OnLogin(player); +#endif FOREACH_SCRIPT(PlayerScript)->OnLogin(player); } @@ -1286,26 +1532,49 @@ void ScriptMgr::OnPlayerLoadFromDB(Player* player) void ScriptMgr::OnPlayerLogout(Player* player) { +#ifdef ELUNA + sEluna->OnLogout(player); +#endif FOREACH_SCRIPT(PlayerScript)->OnLogout(player); } void ScriptMgr::OnPlayerCreate(Player* player) { +#ifdef ELUNA + sEluna->OnCreate(player); +#endif FOREACH_SCRIPT(PlayerScript)->OnCreate(player); } +void ScriptMgr::OnPlayerSave(Player * player) +{ +#ifdef ELUNA + sEluna->OnSave(player); +#endif + FOREACH_SCRIPT(PlayerScript)->OnSave(player); +} + void ScriptMgr::OnPlayerDelete(uint64 guid) { +#ifdef ELUNA + sEluna->OnDelete(GUID_LOPART(guid)); +#endif FOREACH_SCRIPT(PlayerScript)->OnDelete(guid); } void ScriptMgr::OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent) { +#ifdef ELUNA + sEluna->OnBindToInstance(player, difficulty, mapid, permanent); +#endif FOREACH_SCRIPT(PlayerScript)->OnBindToInstance(player, difficulty, mapid, permanent); } void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea) { +#ifdef ELUNA + sEluna->OnUpdateZone(player, newZone, newArea); +#endif FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea); } @@ -1406,63 +1675,99 @@ void ScriptMgr::OnQuestRewardItem(Player* player, Item* item, uint32 count) void ScriptMgr::OnFirstLogin(Player* player) { +#ifdef ELUNA + sEluna->OnFirstLogin(player); +#endif FOREACH_SCRIPT(PlayerScript)->OnFirstLogin(player); } // Guild void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank) { +#ifdef ELUNA + sEluna->OnAddMember(guild, player, plRank); +#endif FOREACH_SCRIPT(GuildScript)->OnAddMember(guild, player, plRank); } void ScriptMgr::OnGuildRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool isKicked) { +#ifdef ELUNA + sEluna->OnRemoveMember(guild, player, isDisbanding); +#endif FOREACH_SCRIPT(GuildScript)->OnRemoveMember(guild, player, isDisbanding, isKicked); } void ScriptMgr::OnGuildMOTDChanged(Guild* guild, const std::string& newMotd) { +#ifdef ELUNA + sEluna->OnMOTDChanged(guild, newMotd); +#endif FOREACH_SCRIPT(GuildScript)->OnMOTDChanged(guild, newMotd); } void ScriptMgr::OnGuildInfoChanged(Guild* guild, const std::string& newInfo) { +#ifdef ELUNA + sEluna->OnInfoChanged(guild, newInfo); +#endif FOREACH_SCRIPT(GuildScript)->OnInfoChanged(guild, newInfo); } void ScriptMgr::OnGuildCreate(Guild* guild, Player* leader, const std::string& name) { +#ifdef ELUNA + sEluna->OnCreate(guild, leader, name); +#endif FOREACH_SCRIPT(GuildScript)->OnCreate(guild, leader, name); } void ScriptMgr::OnGuildDisband(Guild* guild) { +#ifdef ELUNA + sEluna->OnDisband(guild); +#endif FOREACH_SCRIPT(GuildScript)->OnDisband(guild); } void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair) { +#ifdef ELUNA + sEluna->OnMemberWitdrawMoney(guild, player, amount, isRepair); +#endif FOREACH_SCRIPT(GuildScript)->OnMemberWitdrawMoney(guild, player, amount, isRepair); } void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount) { +#ifdef ELUNA + sEluna->OnMemberDepositMoney(guild, player, amount); +#endif FOREACH_SCRIPT(GuildScript)->OnMemberDepositMoney(guild, player, amount); } void ScriptMgr::OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, bool isDestBank, uint8 destContainer, uint8 destSlotId) { +#ifdef ELUNA + sEluna->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); +#endif FOREACH_SCRIPT(GuildScript)->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); } void ScriptMgr::OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) { +#ifdef ELUNA + sEluna->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); +#endif FOREACH_SCRIPT(GuildScript)->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); } void ScriptMgr::OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) { +#ifdef ELUNA + sEluna->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); +#endif FOREACH_SCRIPT(GuildScript)->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); } @@ -1470,30 +1775,45 @@ void ScriptMgr::OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uin void ScriptMgr::OnGroupAddMember(Group* group, uint64 guid) { ASSERT(group); +#ifdef ELUNA + sEluna->OnAddMember(group, guid); +#endif FOREACH_SCRIPT(GroupScript)->OnAddMember(group, guid); } void ScriptMgr::OnGroupInviteMember(Group* group, uint64 guid) { ASSERT(group); +#ifdef ELUNA + sEluna->OnInviteMember(group, guid); +#endif FOREACH_SCRIPT(GroupScript)->OnInviteMember(group, guid); } void ScriptMgr::OnGroupRemoveMember(Group* group, uint64 guid, RemoveMethod method, uint64 kicker, const char* reason) { ASSERT(group); +#ifdef ELUNA + sEluna->OnRemoveMember(group, guid, method); +#endif FOREACH_SCRIPT(GroupScript)->OnRemoveMember(group, guid, method, kicker, reason); } void ScriptMgr::OnGroupChangeLeader(Group* group, uint64 newLeaderGuid, uint64 oldLeaderGuid) { ASSERT(group); +#ifdef ELUNA + sEluna->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); +#endif FOREACH_SCRIPT(GroupScript)->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); } void ScriptMgr::OnGroupDisband(Group* group) { ASSERT(group); +#ifdef ELUNA + sEluna->OnDisband(group); +#endif FOREACH_SCRIPT(GroupScript)->OnDisband(group); } diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 067beef92..6c5b1c6ad 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -221,6 +221,14 @@ class ServerScript : public ScriptObject // Called when a socket is closed. Do not store the socket object, and do not rely on the connection // being open; it is not. virtual void OnSocketClose(WorldSocket* /*socket*/, bool /*wasNew*/) { } + + // Called when a packet is sent to a client. The packet object is a copy of the original packet, so reading + // and modifying it is safe. + virtual void OnPacketSend(WorldSession* /*session*/, WorldPacket& /*packet*/) { } + + // Called when a (valid) packet is received by a client. The packet object is a copy of the original packet, so + // reading and modifying it is safe. Make sure to check WorldSession pointer before usage, it might be null in case of auth packets + virtual void OnPacketReceive(WorldSession* /*session*/, WorldPacket& /*packet*/) { } }; class WorldScript : public ScriptObject @@ -410,6 +418,9 @@ class ItemScript : public ScriptObject // Called when a player uses the item. virtual bool OnUse(Player* /*player*/, Item* /*item*/, SpellCastTargets const& /*targets*/) { return false; } + // Called when the item is destroyed. + virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; } + // Called when the item expires (is destroyed). virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; } @@ -836,6 +847,9 @@ class PlayerScript : public ScriptObject // Called when a player is deleted. virtual void OnDelete(uint64 /*guid*/) { } + // Called when a player is about to be saved. + virtual void OnSave(Player* /*player*/) { } + // Called when a player is bound to an instance virtual void OnBindToInstance(Player* /*player*/, Difficulty /*difficulty*/, uint32 /*mapId*/, bool /*permanent*/) { } @@ -1071,6 +1085,8 @@ class ScriptMgr void OnNetworkStop(); void OnSocketOpen(WorldSocket* socket); void OnSocketClose(WorldSocket* socket, bool wasNew); + void OnPacketReceive(WorldSession* session, WorldPacket const& packet); + void OnPacketSend(WorldSession* session, WorldPacket const& packet); public: /* WorldScript */ @@ -1114,6 +1130,7 @@ class ScriptMgr bool OnQuestAccept(Player* player, Item* item, Quest const* quest); bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets); bool OnItemExpire(Player* player, ItemTemplate const* proto); + bool OnItemRemove(Player* player, Item* item); void OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action); void OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code); @@ -1232,6 +1249,7 @@ class ScriptMgr void OnPlayerLoadFromDB(Player* player); void OnPlayerLogout(Player* player); void OnPlayerCreate(Player* player); + void OnPlayerSave(Player* player); void OnPlayerDelete(uint64 guid); void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent); void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index a2a77df2a..1dcfa89b9 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -35,6 +35,9 @@ #include "WardenMac.h" #include "SavingSystem.h" #include "AccountMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif namespace { @@ -202,6 +205,13 @@ void WorldSession::SendPacket(WorldPacket const* packet) } #endif // !TRINITY_DEBUG + sScriptMgr->OnPacketSend(this, *packet); + +#ifdef ELUNA + if (!sEluna->OnPacketSend(this, *packet)) + return; +#endif + if (m_Socket->SendPacket(*packet) == -1) m_Socket->CloseSocket(); } @@ -276,6 +286,11 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) delete movementPacket; movementPacket = NULL; } + sScriptMgr->OnPacketReceive(this, *packet); +#ifdef ELUNA + if (!sEluna->OnPacketReceive(this, *packet)) + break; +#endif (this->*opHandle.handler)(*packet); } } @@ -288,12 +303,23 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) delete movementPacket; movementPacket = NULL; } + sScriptMgr->OnPacketReceive(this, *packet); +#ifdef ELUNA + if (!sEluna->OnPacketReceive(this, *packet)) + break; +#endif (this->*opHandle.handler)(*packet); } break; case STATUS_AUTHED: if (m_inQueue) // prevent cheating break; + + sScriptMgr->OnPacketReceive(this, *packet); +#ifdef ELUNA + if (!sEluna->OnPacketReceive(this, *packet)) + break; +#endif (this->*opHandle.handler)(*packet); break; case STATUS_NEVER: diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index b16a0b5b5..739a3c79d 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -33,6 +33,9 @@ #include "PacketLog.h" #include "ScriptMgr.h" #include "AccountMgr.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif #if defined(__GNUC__) #pragma pack(1) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index e3a5dccc9..bc4fcbe4e 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -28,6 +28,9 @@ #include "Pet.h" #include "ReputationMgr.h" #include "InstanceScript.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif class Aura; // @@ -6023,6 +6026,11 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* } } else { +#ifdef ELUNA + Creature* c = target->ToCreature(); + if (c && caster && !sEluna->OnDummyEffect(caster, GetId(), SpellEffIndex(GetEffIndex()), target->ToCreature())) + return; +#endif #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefor not triggered.", GetId(), triggerSpellId, GetEffIndex()); #endif diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 19e20c1de..07825c475 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -57,6 +57,9 @@ #include "InstanceScript.h" #include "ReputationMgr.h" #include "Transport.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -773,6 +776,14 @@ void Spell::EffectDummy(SpellEffIndex effIndex) sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell ScriptStart spellid %u in EffectDummy(%u)", m_spellInfo->Id, effIndex); #endif m_caster->GetMap()->ScriptsStart(sSpellScripts, uint32(m_spellInfo->Id | (effIndex << 24)), m_caster, unitTarget); +#ifdef ELUNA + if (gameObjTarget) + sEluna->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget); + else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT) + sEluna->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature()); + else if (itemTarget) + sEluna->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget); +#endif } void Spell::EffectTriggerSpell(SpellEffIndex effIndex) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e59f3a1c7..e06ca40ee 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -76,6 +76,9 @@ #include "AsyncAuctionListing.h" #include "SavingSystem.h" #include +#ifdef ELUNA +#include "LuaEngine.h" +#endif ACE_Atomic_Op World::m_stopEvent = false; uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; @@ -1283,6 +1286,21 @@ void World::SetInitialWorldSettings() vmmgr2->GetLiquidFlagsPtr = &GetLiquidFlags; } +#ifdef ELUNA + ///- Initialize Lua Engine + sLog->outString("Initialize Eluna Lua Engine..."); + + std::string conf_path = _CONF_DIR; + std::string cfg_file = conf_path + "/mod_LuaEngine.conf"; +#ifdef WIN32 + cfg_file = "mod_LuaEngine.conf"; +#endif + std::string cfg_def_file = cfg_file + ".dist"; + sConfigMgr->LoadMore(cfg_def_file.c_str()); + sConfigMgr->LoadMore(cfg_file.c_str()); + Eluna::Initialize(); +#endif + ///- Initialize config settings LoadConfigSettings(); @@ -1868,6 +1886,13 @@ void World::SetInitialWorldSettings() mgr = ChannelMgr::forTeam(TEAM_HORDE); mgr->LoadChannels(); +#ifdef ELUNA + ///- Run eluna scripts. + // in multithread foreach: run scripts + sEluna->RunScripts(); + sEluna->OnConfigLoad(false,false); // Must be done after Eluna is initialized and scripts have run. +#endif + uint32 startupDuration = GetMSTimeDiffToNow(startupBegin); sLog->outString(); sLog->outError("WORLD: World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index cb8a1e1a8..b2cb47e47 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2 * Copyright (C) 2008-2016 TrinityCore * Copyright (C) 2005-2009 MaNGOS diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp index dbb9cd170..26423c2b4 100644 --- a/src/server/worldserver/WorldThread/WorldRunnable.cpp +++ b/src/server/worldserver/WorldThread/WorldRunnable.cpp @@ -22,6 +22,10 @@ #include "AvgDiffTracker.h" #include "AsyncAuctionListing.h" +#ifdef ELUNA +#include "LuaEngine.h" +#endif + #ifdef _WIN32 #include "ServiceWin32.h" extern int m_ServiceStatus; @@ -76,6 +80,9 @@ void WorldRunnable::run() sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world sScriptMgr->Unload(); sOutdoorPvPMgr->Die(); +#ifdef ELUNA + Eluna::Uninitialize(); +#endif } void AuctionListingRunnable::run()