diff --git a/src/common/Utilities/AsyncCallbackProcessor.h b/src/common/Utilities/AsyncCallbackProcessor.h index 76781f4942..d085a569d7 100644 --- a/src/common/Utilities/AsyncCallbackProcessor.h +++ b/src/common/Utilities/AsyncCallbackProcessor.h @@ -53,6 +53,8 @@ class AsyncCallbackProcessor _callbacks.insert(_callbacks.end(), std::make_move_iterator(updateCallbacks.begin()), std::make_move_iterator(updateCallbacks.end())); } + bool HasPendingCallbacks() { return !_callbacks.empty(); } + private: AsyncCallbackProcessor(AsyncCallbackProcessor const&) = delete; AsyncCallbackProcessor& operator=(AsyncCallbackProcessor const&) = delete; diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 0928b1298e..c9dda543ae 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -1534,7 +1534,8 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->Points); #ifdef ELUNA - sEluna->OnAchievementComplete(GetPlayer(), achievement->ID); + if (Eluna* e = GetPlayer()->GetEluna()) + e->OnAchievementComplete(GetPlayer(), achievement->ID); #endif // reward items and titles if any diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 949c69ed1c..698c0135fc 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -149,7 +149,9 @@ Battleground::~Battleground() DelObject(i); #ifdef ELUNA - sEluna->OnBGDestroy(this, GetTypeID(), GetInstanceID()); + if (BattlegroundMap* bg = FindBgMap()) + if (Eluna* e = bg->GetEluna()) + e->OnBGDestroy(this, GetTypeID(), GetInstanceID()); #endif sBattlegroundMgr->RemoveBattleground(GetTypeID(), GetInstanceID()); @@ -457,7 +459,8 @@ inline void Battleground::_ProcessJoin(uint32 diff) StartingEventOpenDoors(); #ifdef ELUNA - sEluna->OnBGStart(this, GetTypeID(), GetInstanceID()); + if (Eluna* e = GetBgMap()->GetEluna()) + e->OnBGStart(this, GetTypeID(), GetInstanceID()); #endif if (StartMessageIds[BG_STARTING_EVENT_FOURTH]) @@ -815,7 +818,8 @@ void Battleground::EndBattleground(uint32 winner) } #ifdef ELUNA //the type of the winner,change Team to BattlegroundTeamId,it could be better. - sEluna->OnBGEnd(this, GetTypeID(), GetInstanceID(), Team(winner)); + if (Eluna* e = GetBgMap()->GetEluna()) + e->OnBGEnd(this, GetTypeID(), GetInstanceID(), Team(winner)); #endif } @@ -990,7 +994,8 @@ void Battleground::StartBattleground() sBattlegroundMgr->AddBattleground(this); #ifdef ELUNA - sEluna->OnBGCreate(this, GetTypeID(), GetInstanceID()); + if (Eluna* e = GetBgMap()->GetEluna()) + e->OnBGCreate(this, GetTypeID(), GetInstanceID()); #endif if (m_IsRated) diff --git a/src/server/game/Chat/ChatCommands/ChatCommand.cpp b/src/server/game/Chat/ChatCommands/ChatCommand.cpp index e7b4be047e..e7c20f5356 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommand.cpp +++ b/src/server/game/Chat/ChatCommands/ChatCommand.cpp @@ -302,7 +302,7 @@ namespace Trinity::Impl::ChatCommands else if (!handler.HasSentErrorMessage()) { /* invocation failed, we should show usage */ #ifdef ELUNA - if (!sEluna->OnCommand(handler.IsConsole() ? NULL : handler.GetSession()->GetPlayer(), std::string(cmdStr).c_str())) + if (!sWorld->GetEluna()->OnCommand(handler.IsConsole() ? nullptr : handler.GetSession()->GetPlayer(), std::string(cmdStr).c_str())) return true; #endif cmd->SendCommandHelp(handler); @@ -312,7 +312,7 @@ namespace Trinity::Impl::ChatCommands } #ifdef ELUNA - if (!sEluna->OnCommand(handler.IsConsole() ? NULL : handler.GetSession()->GetPlayer(), std::string(cmdStr).c_str())) + if (!sWorld->GetEluna()->OnCommand(handler.IsConsole() ? nullptr : handler.GetSession()->GetPlayer(), std::string(cmdStr).c_str())) return true; #endif diff --git a/src/server/game/Combat/CombatManager.cpp b/src/server/game/Combat/CombatManager.cpp index f6411df14d..5f9e6971fa 100644 --- a/src/server/game/Combat/CombatManager.cpp +++ b/src/server/game/Combat/CombatManager.cpp @@ -82,12 +82,14 @@ void CombatReference::EndCombat() if (needFirstAI) { if (Player* player = first->ToPlayer()) - sEluna->OnPlayerLeaveCombat(player); + if (Eluna* e = first->GetEluna()) + e->OnPlayerLeaveCombat(player); } if (needSecondAI) { if (Player* player = second->ToPlayer()) - sEluna->OnPlayerLeaveCombat(player); + if (Eluna* e = second->GetEluna()) + e->OnPlayerLeaveCombat(player); } #endif if (needFirstAI) @@ -128,7 +130,8 @@ void CombatReference::SuppressFor(Unit* who) { #ifdef ELUNA if (Player* player = who->ToPlayer()) - sEluna->OnPlayerLeaveCombat(player); + if (Eluna* e = player->GetEluna()) + e->OnPlayerLeaveCombat(player); #endif if (UnitAI* ai = who->GetAI()) ai->JustExitedCombat(); @@ -325,7 +328,8 @@ void CombatManager::SuppressPvPCombat() { #ifdef ELUNA if (Player* player = _owner->ToPlayer()) - sEluna->OnPlayerLeaveCombat(player); + if (Eluna* e = player->GetEluna()) + e->OnPlayerLeaveCombat(player); #endif if (UnitAI* ownerAI = _owner->GetAI()) ownerAI->JustExitedCombat(); @@ -380,7 +384,8 @@ void CombatManager::EndAllPvPCombat() { #ifdef ELUNA if (Player* player = me->ToPlayer()) - sEluna->OnPlayerEnterCombat(player, other); + if (Eluna* e = player->GetEluna()) + e->OnPlayerEnterCombat(player, other); #endif if (UnitAI* ai = me->GetAI()) ai->JustEnteredCombat(other); diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index d4420b2ace..e816ec5d7b 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -296,7 +296,8 @@ void Creature::AddToWorld() GetZoneScript()->OnCreatureCreate(this); #ifdef ELUNA - sEluna->OnAddToWorld(this); + if (Eluna* e = GetEluna()) + e->OnAddToWorld(this); #endif } } @@ -306,7 +307,8 @@ void Creature::RemoveFromWorld() if (IsInWorld()) { #ifdef ELUNA - sEluna->OnRemoveFromWorld(this); + if (Eluna* e = GetEluna()) + e->OnRemoveFromWorld(this); #endif if (GetZoneScript()) GetZoneScript()->OnCreatureRemove(this); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 9d9959da3b..d0b3a3bdf8 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -231,7 +231,8 @@ void GameObject::AddToWorld() WorldObject::AddToWorld(); #ifdef ELUNA - sEluna->OnAddToWorld(this); + if (Eluna* e = GetEluna()) + e->OnAddToWorld(this); #endif } } @@ -242,7 +243,8 @@ void GameObject::RemoveFromWorld() if (IsInWorld()) { #ifdef ELUNA - sEluna->OnRemoveFromWorld(this); + if (Eluna* e = GetEluna()) + e->OnRemoveFromWorld(this); #endif if (m_zoneScript) m_zoneScript->OnGameObjectRemove(this); @@ -462,7 +464,8 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u void GameObject::Update(uint32 diff) { #ifdef ELUNA - sEluna->UpdateAI(this, diff); + if (Eluna* e = GetEluna()) + e->UpdateAI(this, diff); #endif m_Events.Update(diff); @@ -1634,8 +1637,9 @@ void GameObject::Use(Unit* user) playerUser->PlayerTalkClass->ClearMenus(); #ifdef ELUNA - if (sEluna->OnGossipHello(playerUser, this)) - return; + if (Eluna* e = GetEluna()) + if (e->OnGossipHello(playerUser, this)) + return; #endif if (AI()->OnGossipHello(playerUser)) return; @@ -2426,7 +2430,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldOb case GO_DESTRUCTIBLE_DAMAGED: { #ifdef ELUNA - sEluna->OnDamaged(this, attackerOrHealer); + if (Eluna* e = GetEluna()) + e->OnDamaged(this, attackerOrHealer); #endif EventInform(m_goInfo->building.damagedEvent, attackerOrHealer); AI()->Damaged(attackerOrHealer, m_goInfo->building.damagedEvent); @@ -2454,7 +2459,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldOb case GO_DESTRUCTIBLE_DESTROYED: { #ifdef ELUNA - sEluna->OnDestroyed(this, attackerOrHealer); + if (Eluna* e = GetEluna()) + e->OnDestroyed(this, attackerOrHealer); #endif EventInform(m_goInfo->building.destroyedEvent, attackerOrHealer); AI()->Destroyed(attackerOrHealer, m_goInfo->building.destroyedEvent); @@ -2512,7 +2518,8 @@ void GameObject::SetLootState(LootState state, Unit* unit) m_lootStateUnitGUID.Clear(); #ifdef ELUNA - sEluna->OnLootStateChanged(this, state); + if (Eluna* e = GetEluna()) + e->OnLootStateChanged(this, state); #endif AI()->OnLootStateChanged(state, unit); @@ -2543,7 +2550,8 @@ void GameObject::SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); #ifdef ELUNA - sEluna->OnGameObjectStateChanged(this, state); + if (Eluna* e = GetEluna()) + e->OnGameObjectStateChanged(this, state); #endif if (AI()) AI()->OnStateChanged(state); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index c2f66488d2..5eacbe0a21 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -21,6 +21,7 @@ #include "CellImpl.h" #include "CinematicMgr.h" #include "Common.h" +#include "Config.h" #include "Creature.h" #include "GameTime.h" #include "GridNotifiersImpl.h" @@ -1057,7 +1058,8 @@ void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/) void WorldObject::Update (uint32 time_diff) { #ifdef ELUNA - elunaEvents->Update(time_diff); + if(elunaEvents) // can be null on maps without eluna + elunaEvents->Update(time_diff); #endif } @@ -1840,8 +1842,20 @@ void WorldObject::SetMap(Map* map) m_InstanceId = map->GetInstanceId(); #ifdef ELUNA - if (!elunaEvents) - elunaEvents = new ElunaEventProcessor(&Eluna::GEluna, this); + //@todo: possibly look into cleanly clearing all pending events from previous map's event mgr. + + // if multistate, delete elunaEvents and set to nullptr. events shouldn't move across states. + // in single state, the timed events should move across maps + bool compatMode = sConfigMgr->GetBoolDefault("Eluna.CompatibilityMode", true); + if (!compatMode) + { + delete elunaEvents; + elunaEvents = nullptr; // set to null in case map doesn't use eluna + } + + if(Eluna * e = map->GetEluna()) + if(!elunaEvents) + elunaEvents = new ElunaEventProcessor(e, this); #endif if (IsWorldObject()) @@ -3587,6 +3601,16 @@ std::string WorldObject::GetDebugInfo() const return sstr.str(); } +#ifdef ELUNA +Eluna* WorldObject::GetEluna() const +{ + if (IsInWorld()) + return GetMap()->GetEluna(); + + return nullptr; +} +#endif + template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list&, uint32, float) const; template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::deque&, uint32, float) const; template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::vector&, uint32, float) const; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 08c76e179a..fb9db9edb0 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -34,6 +34,9 @@ #include #include #include +#ifdef ELUNA +#include "LuaValue.h" +#endif class Corpse; class Creature; @@ -56,6 +59,7 @@ class WorldPacket; class ZoneScript; #ifdef ELUNA class ElunaEventProcessor; +class Eluna; #endif struct FactionTemplateEntry; struct PositionFullTerrainStatus; @@ -501,6 +505,10 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation #ifdef ELUNA ElunaEventProcessor* elunaEvents; + + Eluna* GetEluna() const; + + LuaVal lua_data = LuaVal({}); #endif // Transports diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6eb2fe60b6..79db1bdd95 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -784,7 +784,8 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); #ifdef ELUNA - sEluna->OnPlayerKilledByEnvironment(this, type); + if (Eluna* e = GetEluna()) + e->OnPlayerKilledByEnvironment(this, type); #endif } @@ -3560,7 +3561,8 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, uint32 fromSkill /*= 0* SendDirectMessage(&data); #ifdef ELUNA - sEluna->OnLearnSpell(this, spell_id); + if (Eluna* e = GetEluna()) + e->OnLearnSpell(this, spell_id); #endif } @@ -4615,7 +4617,8 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) CastAllObtainSpells(); #ifdef ELUNA - sEluna->OnResurrect(this); + if (Eluna* e = GetEluna()) + e->OnResurrect(this); #endif if (!applySickness) return; @@ -5820,7 +5823,8 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) } } #ifdef ELUNA - sEluna->OnSkillChange(this, SkillId, new_value); + if (Eluna* e = GetEluna()) + e->OnSkillChange(this, SkillId, new_value); #endif UpdateSkillEnchantments(SkillId, SkillValue, new_value); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId); @@ -7050,8 +7054,9 @@ void Player::UpdateArea(uint32 newArea) #ifdef ELUNA // We only want the hook to trigger when the old and new area is actually different - if(oldArea != newArea) - sEluna->OnUpdateArea(this, oldArea, newArea); + if (Eluna* e = GetEluna()) + if(oldArea != newArea) + e->OnUpdateArea(this, oldArea, newArea); #endif } @@ -11816,9 +11821,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const return EQUIP_ERR_NONE; #ifdef ELUNA - InventoryResult eres = sEluna->OnCanUseItem(this, proto->ItemId); - if (eres != EQUIP_ERR_OK) - return eres; + if (Eluna* e = GetEluna()) + { + InventoryResult eres = e->OnCanUseItem(this, proto->ItemId); + if (eres != EQUIP_ERR_OK) + return eres; + } #endif return EQUIP_ERR_OK; @@ -12002,7 +12010,8 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update } #ifdef ELUNA - sEluna->OnAdd(this, pItem); + if (Eluna* e = GetEluna()) + e->OnAdd(this, pItem); #endif } return pItem; @@ -12249,7 +12258,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) ApplyEquipCooldown(pItem2); #ifdef ELUNA - sEluna->OnEquip(this, pItem2, bag, slot); + if (Eluna* e = GetEluna()) + e->OnEquip(this, pItem2, bag, slot); #endif return pItem2; } @@ -12262,7 +12272,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, slot, pItem->GetEntry()); #ifdef ELUNA - sEluna->OnEquip(this, pItem, bag, slot); + if (Eluna* e = GetEluna()) + e->OnEquip(this, pItem, bag, slot); #endif return pItem; } @@ -12290,7 +12301,8 @@ void Player::QuickEquipItem(uint16 pos, Item* pItem) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, slot, pItem->GetEntry()); #ifdef ELUNA - sEluna->OnEquip(this, pItem, (pos >> 8), slot); + if (Eluna* e = GetEluna()) + e->OnEquip(this, pItem, (pos >> 8), slot); #endif } } @@ -14957,7 +14969,8 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver) PlayerTalkClass->ClearMenus(); #ifdef ELUNA - sEluna->OnQuestAccept(this, questGiver->ToCreature(), quest); + if (Eluna* e = GetEluna()) + e->OnQuestAccept(this, questGiver->ToCreature(), quest); #endif questGiver->ToCreature()->AI()->OnQuestAccept(this, quest); @@ -14994,7 +15007,8 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver) PlayerTalkClass->ClearMenus(); #ifdef ELUNA - sEluna->OnQuestAccept(this, questGiver->ToGameObject(), quest); + if (Eluna* e = GetEluna()) + e->OnQuestAccept(this, questGiver->ToGameObject(), quest); #endif questGiver->ToGameObject()->AI()->OnQuestAccept(this, quest); @@ -16119,7 +16133,8 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) case TYPEID_GAMEOBJECT: { #ifdef ELUNA - sEluna->GetDialogStatus(this, questgiver->ToGameObject()); + if (Eluna* e = GetEluna()) + e->GetDialogStatus(this, questgiver->ToGameObject()); #endif if (auto ai = questgiver->ToGameObject()->AI()) if (auto questStatus = ai->GetDialogStatus(this)) @@ -16131,7 +16146,8 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) case TYPEID_UNIT: { #ifdef ELUNA - sEluna->GetDialogStatus(this, questgiver->ToCreature()); + if (Eluna* e = GetEluna()) + e->GetDialogStatus(this, questgiver->ToCreature()); #endif if (auto ai = questgiver->ToCreature()->AI()) if (auto questStatus = ai->GetDialogStatus(this)) @@ -24991,7 +25007,8 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) sLootItemStorage->RemoveStoredLootItemForContainer(loot->containerID, item->itemid, item->count, item->itemIndex); #ifdef ELUNA - sEluna->OnLootItem(this, newitem, item->count, this->GetLootGUID()); + if (Eluna* e = GetEluna()) + e->OnLootItem(this, newitem, item->count, this->GetLootGUID()); #endif } else @@ -25410,7 +25427,8 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1)); #ifdef ELUNA - sEluna->OnLearnTalents(this, talentId, talentRank, spellid); + if (Eluna* e = GetEluna()) + e->OnLearnTalents(this, talentId, talentRank, spellid); #endif } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 21eb33a698..073fcd95bc 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -435,7 +435,8 @@ Unit::~Unit() void Unit::Update(uint32 p_time) { #ifdef ELUNA - elunaEvents->Update(p_time); + if(elunaEvents) // can be null on maps without eluna + elunaEvents->Update(p_time); #endif // WARNING! Order of execution here is important, do not change. diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 051d6bee70..1cde4437c8 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -149,7 +149,7 @@ bool GameEventMgr::StartEvent(uint16 event_id, bool overwrite) sWorld->setWorldState(event_id, GameTime::GetGameTime()); #ifdef ELUNA if (IsActiveEvent(event_id)) - sEluna->OnGameEventStart(event_id); + sWorld->GetEluna()->OnGameEventStart(event_id); #endif return false; } @@ -176,7 +176,7 @@ bool GameEventMgr::StartEvent(uint16 event_id, bool overwrite) #ifdef ELUNA if (IsActiveEvent(event_id)) - sEluna->OnGameEventStart(event_id); + sWorld->GetEluna()->OnGameEventStart(event_id); #endif return conditions_met; } @@ -226,7 +226,7 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite) #ifdef ELUNA if (!IsActiveEvent(event_id)) - sEluna->OnGameEventStop(event_id); + sWorld->GetEluna()->OnGameEventStop(event_id); #endif } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 4075d060e9..2d0fce4136 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -219,7 +219,8 @@ bool Group::Create(Player* leader) return false; #ifdef ELUNA - sEluna->OnCreate(this, m_leaderGuid, m_groupType); + if (Eluna* e = leader->GetEluna()) + e->OnCreate(this, m_leaderGuid, m_groupType); #endif return true; diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 271459459c..c5bc8a6b97 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -294,7 +294,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } #ifdef ELUNA - if (!sEluna->OnChat(sender, type, lang, msg)) + if (!sWorld->GetEluna()->OnChat(sender, type, lang, msg)) return; #endif @@ -314,7 +314,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } #ifdef ELUNA - if (!sEluna->OnChat(sender, type, LANG_UNIVERSAL, msg)) + if (!sWorld->GetEluna()->OnChat(sender, type, LANG_UNIVERSAL, msg)) return; #endif @@ -334,7 +334,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) } #ifdef ELUNA - if (!sEluna->OnChat(sender, type, lang, msg)) + if (!sWorld->GetEluna()->OnChat(sender, type, lang, msg)) return; #endif @@ -385,7 +385,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sender->AddWhisperWhiteList(receiver->GetGUID()); #ifdef ELUNA - if (!sEluna->OnChat(GetPlayer(), type, lang, msg, receiver)) + if (!sWorld->GetEluna()->OnChat(GetPlayer(), type, lang, msg, receiver)) return; #endif GetPlayer()->Whisper(msg, Language(lang), receiver); @@ -408,7 +408,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, group)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, group)) return; #endif @@ -425,7 +425,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, guild)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, guild)) return; #endif @@ -442,7 +442,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, guild)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, guild)) return; #endif @@ -464,7 +464,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, group)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, group)) return; #endif @@ -486,7 +486,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, group)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, group)) return; #endif @@ -503,7 +503,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, group)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, group)) return; #endif @@ -522,7 +522,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, group)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, group)) return; #endif @@ -540,7 +540,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, group)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, group)) return; #endif @@ -564,7 +564,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg, chn)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg, chn)) return; #endif chn->Say(sender->GetGUID(), msg, lang); @@ -594,7 +594,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(sender, type, lang, msg); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg)) return; #endif } @@ -621,7 +621,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(sender, type, lang, msg); #ifdef ELUNA - if(!sEluna->OnChat(sender, type, lang, msg)) + if(!sWorld->GetEluna()->OnChat(sender, type, lang, msg)) return; #endif break; diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index b0b12888b7..b303df7f7a 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -245,8 +245,9 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData) } #ifdef ELUNA - if (!sEluna->OnMemberAccept(group, GetPlayer())) - return; + if (Eluna* e = GetPlayer()->GetEluna()) + if (!e->OnMemberAccept(group, GetPlayer())) + return; #endif Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index e48b923228..14e3f7632e 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -208,7 +208,8 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) } #ifdef ELUNA - sEluna->OnLootMoney(player, loot->gold); + if (Eluna* e = player->GetEluna()) + e->OnLootMoney(player, loot->gold); #endif loot->gold = 0; @@ -484,7 +485,8 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); #ifdef ELUNA - sEluna->OnLootItem(target, newitem, item.count, lootguid); + if (Eluna* e = target->GetEluna()) + e->OnLootItem(target, newitem, item.count, lootguid); #endif // mark as looted item.count = 0; diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index ae31ddbf3c..e39bc7fdf9 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -229,10 +229,13 @@ void WorldSession::HandleSendMail(WorldPackets::Mail::SendMail& sendMail) } #ifdef ELUNA - if (!sEluna->OnSendMail(player, receiverGuid)) + if (Eluna* e = player->GetEluna()) { - player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CANT_DO_RIGHT_NOW); - return; + if (!e->OnSendMail(player, receiverGuid)) + { + player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CANT_DO_RIGHT_NOW); + return; + } } #endif diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index f7862e5a83..8861160ac7 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -81,7 +81,8 @@ void WorldSession::HandleRepopRequest(WorldPackets::Misc::RepopRequest& /*packet } #ifdef ELUNA - sEluna->OnRepop(GetPlayer()); + if (Eluna* e = GetPlayer()->GetEluna()) + e->OnRepop(GetPlayer()); #endif //this is spirit release confirm? @@ -179,7 +180,8 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) { #ifdef ELUNA - if (!sEluna->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str())) + if (Eluna* e = GetPlayer()->GetEluna()) + if (!e->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str())) #endif if (!unit->AI()->OnGossipSelectCode(_player, menuId, gossipListId, code.c_str())) _player->OnGossipSelect(unit, gossipListId, menuId); @@ -195,7 +197,8 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) else { #ifdef ELUNA - if (!sEluna->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str())) + if (Eluna* e = GetPlayer()->GetEluna()) + if (!e->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str())) #endif if (!go->AI()->OnGossipSelectCode(_player, menuId, gossipListId, code.c_str())) _player->OnGossipSelect(go, gossipListId, menuId); @@ -206,7 +209,8 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) if (unit) { #ifdef ELUNA - if (!sEluna->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId))) + if (Eluna* e = GetPlayer()->GetEluna()) + if (!e->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId))) #endif if (!unit->AI()->OnGossipSelect(_player, menuId, gossipListId)) _player->OnGossipSelect(unit, gossipListId, menuId); @@ -222,7 +226,8 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) else { #ifdef ELUNA - if (!sEluna->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId))) + if (Eluna* e = GetPlayer()->GetEluna()) + if (!e->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId))) #endif if (!go->AI()->OnGossipSelect(_player, menuId, gossipListId)) _player->OnGossipSelect(go, gossipListId, menuId); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 283e06351f..a9f927febe 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -186,7 +186,8 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData) _player->PlayerTalkClass->ClearMenus(); #ifdef ELUNA - if (!sEluna->OnGossipHello(_player, unit)) + if (Eluna* e = GetPlayer()->GetEluna()) + if (!e->OnGossipHello(_player, unit)) #endif if (!unit->AI()->OnGossipHello(_player)) { diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 48b53a76cf..08dcec9dca 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -102,8 +102,9 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData) _player->PlayerTalkClass->ClearMenus(); #ifdef ELUNA - if (sEluna->OnGossipHello(_player, creature)) - return; + if (Eluna* e = GetPlayer()->GetEluna()) + if (e->OnGossipHello(_player, creature)) + return; #endif if (creature->AI()->OnGossipHello(_player)) @@ -328,7 +329,8 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) _player->PlayerTalkClass->ClearMenus(); #ifdef ELUNA - sEluna->OnQuestReward(_player, questgiver, quest, reward); + if (Eluna* e = GetPlayer()->GetEluna()) + e->OnQuestReward(_player, questgiver, quest, reward); #endif questgiver->AI()->OnQuestReward(_player, quest, reward); @@ -352,7 +354,8 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) _player->PlayerTalkClass->ClearMenus(); #ifdef ELUNA - sEluna->OnQuestReward(_player, questGiver, quest, reward); + if (Eluna* e = GetPlayer()->GetEluna()) + e->OnQuestReward(_player, questGiver, quest, reward); #endif questGiver->AI()->OnQuestReward(_player, quest, reward); break; @@ -445,7 +448,8 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) _player->RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId); #ifdef ELUNA - sEluna->OnQuestAbandon(_player, questId); + if (Eluna* e = GetPlayer()->GetEluna()) + e->OnQuestAbandon(_player, questId); #endif TC_LOG_INFO("network", "Player {} abandoned quest {}", _player->GetGUID().ToString(), questId); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index a3eb4694b5..3e9b80c668 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -320,8 +320,9 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(guid)) { #ifdef ELUNA - if (sEluna->OnGameObjectUse(_player, go)) - return; + if (Eluna* e = GetPlayer()->GetEluna()) + if (e->OnGameObjectUse(_player, go)) + return; #endif if (go->AI()->OnReportUse(_player)) return; diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index c3c4d9165b..72b987426f 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -354,13 +354,16 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) } #ifdef ELUNA - if (!sEluna->OnTradeAccept(_player, trader)) + if (Eluna* e = _player->GetEluna()) { - info.Status = TRADE_STATUS_CLOSE_WINDOW; - info.Result = EQUIP_ERR_CANT_DO_RIGHT_NOW; - SendTradeStatus(info); - my_trade->SetAccepted(false, true); - return; + if (!e->OnTradeAccept(_player, trader)) + { + info.Status = TRADE_STATUS_CLOSE_WINDOW; + info.Result = EQUIP_ERR_CANT_DO_RIGHT_NOW; + SendTradeStatus(info); + my_trade->SetAccepted(false, true); + return; + } } #endif @@ -705,11 +708,14 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) } #ifdef ELUNA - if (!sEluna->OnTradeInit(GetPlayer(), pOther)) + if (Eluna* e = GetPlayer()->GetEluna()) { - info.Status = TRADE_STATUS_BUSY; - SendTradeStatus(info); - return; + if (!e->OnTradeInit(GetPlayer(), pOther)) + { + info.Status = TRADE_STATUS_BUSY; + SendTradeStatus(info); + return; + } } #endif diff --git a/src/server/game/LuaEngine b/src/server/game/LuaEngine index f8f97c55f7..b6838d52e2 160000 --- a/src/server/game/LuaEngine +++ b/src/server/game/LuaEngine @@ -1 +1 @@ -Subproject commit f8f97c55f79a7563c29b0a7c917babef96cdbe0c +Subproject commit b6838d52e264aae01e774f089a6fd4bc7ff83f59 diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 3d12c3c9bc..43f784b84e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -18,6 +18,7 @@ #include "Map.h" #include "Battleground.h" #include "CellImpl.h" +#include "Config.h" #include "DatabaseEnv.h" #include "DisableMgr.h" #include "DynamicTree.h" @@ -46,6 +47,7 @@ #include "VMapFactory.h" #ifdef ELUNA #include "LuaEngine.h" +#include "ElunaLoader.h" #endif #include "VMapManager2.h" #include "Weather.h" @@ -97,6 +99,11 @@ Map::~Map() sScriptMgr->OnDestroyMap(this); +#ifdef ELUNA + delete eluna; + eluna = nullptr; +#endif + // Delete all waiting spawns, else there will be a memory leak // This doesn't delete from database. UnloadAllRespawnInfos(); @@ -289,6 +296,15 @@ i_gridExpiry(expiry), i_scriptLock(false), _respawnTimes(std::make_unique()), _respawnCheckTimer(0) { m_parentMap = (_parent ? _parent : this); +#ifdef ELUNA + // lua state begins uninitialized + eluna = nullptr; + + bool compatMode = sConfigMgr->GetBoolDefault("Eluna.CompatibilityMode", true); + if (sElunaLoader->ShouldMapLoadEluna(id) && !compatMode) + if (!IsParentMap() || (IsParentMap() && !Instanceable())) + eluna = new Eluna(this); +#endif for (unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx) { for (unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) @@ -3578,10 +3594,13 @@ void Map::AddObjectToRemoveList(WorldObject* obj) ASSERT(obj->GetMapId() == GetId() && obj->GetInstanceId() == GetInstanceId()); #ifdef ELUNA - if (Creature* creature = obj->ToCreature()) - sEluna->OnRemove(creature); - else if (GameObject* gameobject = obj->ToGameObject()) - sEluna->OnRemove(gameobject); + if (Eluna* e = GetEluna()) + { + if (Creature* creature = obj->ToCreature()) + e->OnRemove(creature); + else if (GameObject* gameobject = obj->ToGameObject()) + e->OnRemove(gameobject); + } #endif obj->CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links @@ -4036,9 +4055,12 @@ void InstanceMap::CreateInstanceData(bool load) bool isElunaAI = false; #ifdef ELUNA - i_data = sEluna->GetInstanceData(this); - if (i_data) - isElunaAI = true; + if (Eluna* e = GetEluna()) + { + i_data = e->GetInstanceData(this); + if (i_data) + isElunaAI = true; + } #endif // if Eluna AI was fetched succesfully we should not call CreateInstanceData nor set the unused scriptID @@ -4881,4 +4903,13 @@ std::string InstanceMap::GetDebugInfo() const return sstr.str(); } +Eluna *Map::GetEluna() const +{ + bool compatMode = sConfigMgr->GetBoolDefault("Eluna.CompatibilityMode", true); + if(compatMode) + return sWorld->GetEluna(); + + return eluna; +} + template class TC_GAME_API TypeUnorderedMapContainer; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index dadd8cc14d..2216ccbc78 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -36,10 +36,16 @@ #include #include #include +#ifdef ELUNA +#include "LuaValue.h" +#endif class Battleground; class BattlegroundMap; class CreatureGroup; +#ifdef ELUNA +class Eluna; +#endif class GameObjectModel; class Group; class InstanceMap; @@ -815,7 +821,12 @@ class TC_GAME_API Map : public GridRefManager typedef std::function FarSpellCallback; void AddFarSpellCallback(FarSpellCallback&& callback); + bool IsParentMap() const { return GetParent() == this; } +#ifdef ELUNA + Eluna* GetEluna() const; + LuaVal lua_data = LuaVal({}); +#endif private: // Type specific code for add/remove to/from grid template @@ -895,6 +906,9 @@ class TC_GAME_API Map : public GridRefManager std::unordered_set _updateObjects; MPSCQueue _farSpellCallbacks; +#ifdef ELUNA + Eluna* eluna; +#endif }; enum InstanceResetMethod diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 1fd5546a97..84bbe37090 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -17,6 +17,7 @@ #include "MapManager.h" #include "InstanceSaveMgr.h" +#include "Config.h" #include "DatabaseEnv.h" #include "Log.h" #include "ObjectAccessor.h" @@ -52,14 +53,15 @@ void MapManager::Initialize() int num_threads(sWorld->getIntConfig(CONFIG_NUMTHREADS)); #if ELUNA - if (num_threads > 1) + bool compatMode = sConfigMgr->GetBoolDefault("Eluna.CompatibilityMode", true); + if (compatMode && num_threads > 1) { - // Force 1 thread for Eluna as lua is single threaded. By default thread count is 1 - // This should allow us not to use mutex locks - TC_LOG_ERROR("maps", "Map update threads set to {}, when Eluna only allows 1, changing to 1", num_threads); + // Force 1 thread for Eluna if compatibility mode is enabled. Compatibility mode is single state and does not allow more update threads. + TC_LOG_ERROR("maps", "Map update threads set to {}, when Eluna in compatibility mode only allows 1, changing to 1", num_threads); num_threads = 1; } #endif + // Start mtmaps if needed. if (num_threads > 0) m_updater.activate(num_threads); @@ -371,6 +373,15 @@ void MapManager::FreeInstanceId(uint32 instanceId) _nextInstanceId = std::min(instanceId, _nextInstanceId); _freeInstanceIds[instanceId] = true; #ifdef ELUNA - sEluna->FreeInstanceId(instanceId); + for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) + { + Map* map = itr->second; + if (!map->Instanceable()) + continue; + + Map* iMap = ((MapInstanced*)map)->FindInstanceMap(instanceId); + if (iMap && iMap->GetEluna()) + iMap->GetEluna()->FreeInstanceId(instanceId); + } #endif } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 1b9d3c3119..5a5e3a8168 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1316,7 +1316,7 @@ void ScriptMgr::OnPacketSend(WorldSession* session, WorldPacket const& packet) void ScriptMgr::OnOpenStateChange(bool open) { #ifdef ELUNA - sEluna->OnOpenStateChange(open); + sWorld->GetEluna()->OnOpenStateChange(open); #endif FOREACH_SCRIPT(WorldScript)->OnOpenStateChange(open); } @@ -1324,7 +1324,7 @@ void ScriptMgr::OnOpenStateChange(bool open) void ScriptMgr::OnConfigLoad(bool reload) { #ifdef ELUNA - sEluna->OnConfigLoad(reload); + sWorld->GetEluna()->OnConfigLoad(reload); #endif FOREACH_SCRIPT(WorldScript)->OnConfigLoad(reload); } @@ -1337,7 +1337,7 @@ void ScriptMgr::OnMotdChange(std::string& newMotd) void ScriptMgr::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) { #ifdef ELUNA - sEluna->OnShutdownInitiate(code, mask); + sWorld->GetEluna()->OnShutdownInitiate(code, mask); #endif FOREACH_SCRIPT(WorldScript)->OnShutdownInitiate(code, mask); } @@ -1345,7 +1345,7 @@ void ScriptMgr::OnShutdownInitiate(ShutdownExitCode code, ShutdownMask mask) void ScriptMgr::OnShutdownCancel() { #ifdef ELUNA - sEluna->OnShutdownCancel(); + sWorld->GetEluna()->OnShutdownCancel(); #endif FOREACH_SCRIPT(WorldScript)->OnShutdownCancel(); } @@ -1353,7 +1353,8 @@ void ScriptMgr::OnShutdownCancel() void ScriptMgr::OnWorldUpdate(uint32 diff) { #ifdef ELUNA - sEluna->OnWorldUpdate(diff); + sWorld->GetEluna()->UpdateEluna(diff); + sWorld->GetEluna()->OnWorldUpdate(diff); #endif FOREACH_SCRIPT(WorldScript)->OnUpdate(diff); } @@ -1418,7 +1419,8 @@ void ScriptMgr::OnCreateMap(Map* map) ASSERT(map); #ifdef ELUNA - sEluna->OnCreate(map); + if (Eluna* e = map->GetEluna()) + e->OnCreate(map); #endif SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); @@ -1439,7 +1441,8 @@ void ScriptMgr::OnDestroyMap(Map* map) ASSERT(map); #ifdef ELUNA - sEluna->OnDestroy(map); + if (Eluna* e = map->GetEluna()) + e->OnDestroy(map); #endif SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); @@ -1497,8 +1500,10 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player) ASSERT(player); #ifdef ELUNA - sEluna->OnMapChanged(player); - sEluna->OnPlayerEnter(map, player); + if(Eluna * e = player->GetEluna()) + e->OnMapChanged(player); + if (Eluna* e = map->GetEluna()) + e->OnPlayerEnter(map, player); #endif FOREACH_SCRIPT(PlayerScript)->OnMapChanged(player); @@ -1522,7 +1527,8 @@ void ScriptMgr::OnPlayerLeaveMap(Map* map, Player* player) ASSERT(player); #ifdef ELUNA - sEluna->OnPlayerLeave(map, player); + if(Eluna * e = map->GetEluna()) + e->OnPlayerLeave(map, player); #endif SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); @@ -1543,7 +1549,14 @@ void ScriptMgr::OnMapUpdate(Map* map, uint32 diff) ASSERT(map); #ifdef ELUNA - sEluna->OnUpdate(map, diff); + if (Eluna* e = map->GetEluna()) + { + bool compatMode = sConfigMgr->GetBoolDefault("Eluna.CompatibilityMode", true); + if(!compatMode) + e->UpdateEluna(diff); + + e->OnUpdate(map, diff); + } #endif SCR_MAP_BGN(WorldMapScript, map, itr, end, entry, IsWorldMap); @@ -1576,8 +1589,9 @@ bool ScriptMgr::OnQuestAccept(Player* player, Item* item, Quest const* quest) ASSERT(item); ASSERT(quest); #ifdef ELUNA - if (sEluna->OnQuestAccept(player, item, quest)) - return false; + if(Eluna * e = player->GetEluna()) + if (e->OnQuestAccept(player, item, quest)) + return false; #endif GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); @@ -1590,8 +1604,9 @@ bool ScriptMgr::OnItemUse(Player* player, Item* item, SpellCastTargets const& ta ASSERT(player); ASSERT(item); #ifdef ELUNA - if (!sEluna->OnUse(player, item, targets)) - return true; + if (Eluna* e = player->GetEluna()) + if (!e->OnUse(player, item, targets)) + return true; #endif GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); @@ -1603,8 +1618,9 @@ bool ScriptMgr::OnItemExpire(Player* player, ItemTemplate const* proto) ASSERT(player); ASSERT(proto); #ifdef ELUNA - if (sEluna->OnExpire(player, proto)) - return false; + if (Eluna* e = player->GetEluna()) + if (e->OnExpire(player, proto)) + return false; #endif GET_SCRIPT_RET(ItemScript, proto->ScriptId, tmpscript, false); @@ -1616,8 +1632,9 @@ bool ScriptMgr::OnItemRemove(Player* player, Item* item) ASSERT(player); ASSERT(item); #ifdef ELUNA - if (sEluna->OnRemove(player, item)) - return false; + if (Eluna* e = player->GetEluna()) + if (e->OnRemove(player, item)) + return false; #endif GET_SCRIPT_RET(ItemScript, item->GetScriptId(), tmpscript, false); @@ -1640,7 +1657,8 @@ void ScriptMgr::OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 ASSERT(player); ASSERT(item); #ifdef ELUNA - sEluna->HandleGossipSelectOption(player, item, sender, action, ""); + if (Eluna* e = player->GetEluna()) + e->HandleGossipSelectOption(player, item, sender, action, ""); #endif GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript); @@ -1652,7 +1670,8 @@ void ScriptMgr::OnGossipSelectCode(Player* player, Item* item, uint32 sender, ui ASSERT(player); ASSERT(item); #ifdef ELUNA - sEluna->HandleGossipSelectOption(player, item, sender, action, code); + if (Eluna* e = player->GetEluna()) + e->HandleGossipSelectOption(player, item, sender, action, code); #endif GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript); @@ -1663,8 +1682,9 @@ CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature) { ASSERT(creature); #ifdef ELUNA - if (CreatureAI* luaAI = sEluna->GetAI(creature)) - return luaAI; + if (Eluna* e = creature->GetEluna()) + if (CreatureAI* luaAI = e->GetAI(creature)) + return luaAI; #endif GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, nullptr); @@ -1675,7 +1695,8 @@ GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* gameobject) { ASSERT(gameobject); #ifdef ELUNA - sEluna->OnSpawn(gameobject); + if (Eluna* e = gameobject->GetEluna()) + e->OnSpawn(gameobject); #endif GET_SCRIPT_RET(GameObjectScript, gameobject->GetScriptId(), tmpscript, nullptr); @@ -1687,8 +1708,9 @@ bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger) ASSERT(player); ASSERT(trigger); #ifdef ELUNA - if (sEluna->OnAreaTrigger(player, trigger)) - return false; + if (Eluna* e = player->GetEluna()) + if (e->OnAreaTrigger(player, trigger)) + return false; #endif GET_SCRIPT_RET(AreaTriggerScript, sObjectMgr->GetAreaTriggerScriptId(trigger->ID), tmpscript, false); @@ -1731,7 +1753,7 @@ void ScriptMgr::OnWeatherChange(Weather* weather, WeatherState state, float grad { ASSERT(weather); #ifdef ELUNA - sEluna->OnChange(weather, weather->GetZone(), state, grade); + sWorld->GetEluna()->OnChange(weather, weather->GetZone(), state, grade); #endif GET_SCRIPT(WeatherScript, weather->GetScriptId(), tmpscript); @@ -1751,7 +1773,7 @@ void ScriptMgr::OnAuctionAdd(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); #ifdef ELUNA - sEluna->OnAdd(ah, entry); + sWorld->GetEluna()->OnAdd(ah, entry); #endif FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionAdd(ah, entry); @@ -1762,7 +1784,7 @@ void ScriptMgr::OnAuctionRemove(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); #ifdef ELUNA - sEluna->OnRemove(ah, entry); + sWorld->GetEluna()->OnRemove(ah, entry); #endif FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionRemove(ah, entry); @@ -1773,7 +1795,7 @@ void ScriptMgr::OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); #ifdef ELUNA - sEluna->OnSuccessful(ah, entry); + sWorld->GetEluna()->OnSuccessful(ah, entry); #endif FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionSuccessful(ah, entry); @@ -1784,7 +1806,7 @@ void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry) ASSERT(ah); ASSERT(entry); #ifdef ELUNA - sEluna->OnExpire(ah, entry); + sWorld->GetEluna()->OnExpire(ah, entry); #endif FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry); @@ -1803,7 +1825,8 @@ void ScriptMgr::OnInstall(Vehicle* veh) ASSERT(veh); ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); #ifdef ELUNA - sEluna->OnInstall(veh); + if(Eluna * e = veh->GetBase()->GetEluna()) + e->OnInstall(veh); #endif GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); @@ -1815,7 +1838,8 @@ void ScriptMgr::OnUninstall(Vehicle* veh) ASSERT(veh); ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); #ifdef ELUNA - sEluna->OnUninstall(veh); + if (Eluna* e = veh->GetBase()->GetEluna()) + e->OnUninstall(veh); #endif GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); @@ -1837,7 +1861,8 @@ void ScriptMgr::OnInstallAccessory(Vehicle* veh, Creature* accessory) ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); ASSERT(accessory); #ifdef ELUNA - sEluna->OnInstallAccessory(veh, accessory); + if (Eluna* e = veh->GetBase()->GetEluna()) + e->OnInstallAccessory(veh, accessory); #endif GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); @@ -1850,7 +1875,8 @@ void ScriptMgr::OnAddPassenger(Vehicle* veh, Unit* passenger, int8 seatId) ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); ASSERT(passenger); #ifdef ELUNA - sEluna->OnAddPassenger(veh, passenger, seatId); + if (Eluna* e = veh->GetBase()->GetEluna()) + e->OnAddPassenger(veh, passenger, seatId); #endif GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); @@ -1863,7 +1889,8 @@ void ScriptMgr::OnRemovePassenger(Vehicle* veh, Unit* passenger) ASSERT(veh->GetBase()->GetTypeId() == TYPEID_UNIT); ASSERT(passenger); #ifdef ELUNA - sEluna->OnRemovePassenger(veh, passenger); + if (Eluna* e = veh->GetBase()->GetEluna()) + e->OnRemovePassenger(veh, passenger); #endif GET_SCRIPT(VehicleScript, veh->GetBase()->ToCreature()->GetScriptId(), tmpscript); @@ -1922,7 +1949,7 @@ void ScriptMgr::OnRelocate(Transport* transport, uint32 waypointId, uint32 mapId void ScriptMgr::OnStartup() { #ifdef ELUNA - sEluna->OnStartup(); + sWorld->GetEluna()->OnStartup(); #endif FOREACH_SCRIPT(WorldScript)->OnStartup(); } @@ -1930,7 +1957,7 @@ void ScriptMgr::OnStartup() void ScriptMgr::OnShutdown() { #ifdef ELUNA - sEluna->OnShutdown(); + sWorld->GetEluna()->OnShutdown(); #endif FOREACH_SCRIPT(WorldScript)->OnShutdown(); } @@ -1948,7 +1975,8 @@ bool ScriptMgr::OnCriteriaCheck(uint32 scriptId, Player* source, Unit* target) void ScriptMgr::OnPVPKill(Player* killer, Player* killed) { #ifdef ELUNA - sEluna->OnPVPKill(killer, killed); + if (Eluna* e = killer->GetEluna()) + e->OnPVPKill(killer, killed); #endif FOREACH_SCRIPT(PlayerScript)->OnPVPKill(killer, killed); } @@ -1956,7 +1984,8 @@ void ScriptMgr::OnPVPKill(Player* killer, Player* killed) void ScriptMgr::OnCreatureKill(Player* killer, Creature* killed) { #ifdef ELUNA - sEluna->OnCreatureKill(killer, killed); + if(Eluna * e = killer->GetEluna()) + e->OnCreatureKill(killer, killed); #endif FOREACH_SCRIPT(PlayerScript)->OnCreatureKill(killer, killed); } @@ -1964,7 +1993,8 @@ void ScriptMgr::OnCreatureKill(Player* killer, Creature* killed) void ScriptMgr::OnPlayerKilledByCreature(Creature* killer, Player* killed) { #ifdef ELUNA - sEluna->OnPlayerKilledByCreature(killer, killed); + if (Eluna* e = killer->GetEluna()) + e->OnPlayerKilledByCreature(killer, killed); #endif FOREACH_SCRIPT(PlayerScript)->OnPlayerKilledByCreature(killer, killed); } @@ -1972,7 +2002,8 @@ void ScriptMgr::OnPlayerKilledByCreature(Creature* killer, Player* killed) void ScriptMgr::OnPlayerLevelChanged(Player* player, uint8 oldLevel) { #ifdef ELUNA - sEluna->OnLevelChanged(player, oldLevel); + if (Eluna* e = player->GetEluna()) + e->OnLevelChanged(player, oldLevel); #endif FOREACH_SCRIPT(PlayerScript)->OnLevelChanged(player, oldLevel); } @@ -1980,7 +2011,8 @@ void ScriptMgr::OnPlayerLevelChanged(Player* player, uint8 oldLevel) void ScriptMgr::OnPlayerFreeTalentPointsChanged(Player* player, uint32 points) { #ifdef ELUNA - sEluna->OnFreeTalentPointsChanged(player, points); + if (Eluna* e = player->GetEluna()) + e->OnFreeTalentPointsChanged(player, points); #endif FOREACH_SCRIPT(PlayerScript)->OnFreeTalentPointsChanged(player, points); } @@ -1988,7 +2020,8 @@ void ScriptMgr::OnPlayerFreeTalentPointsChanged(Player* player, uint32 points) void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost) { #ifdef ELUNA - sEluna->OnTalentsReset(player, noCost); + if (Eluna* e = player->GetEluna()) + e->OnTalentsReset(player, noCost); #endif FOREACH_SCRIPT(PlayerScript)->OnTalentsReset(player, noCost); } @@ -1996,7 +2029,8 @@ void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost) void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount) { #ifdef ELUNA - sEluna->OnMoneyChanged(player, amount); + if (Eluna* e = player->GetEluna()) + e->OnMoneyChanged(player, amount); #endif FOREACH_SCRIPT(PlayerScript)->OnMoneyChanged(player, amount); } @@ -2009,7 +2043,8 @@ void ScriptMgr::OnPlayerMoneyLimit(Player* player, int32 amount) void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim) { #ifdef ELUNA - sEluna->OnGiveXP(player, amount, victim); + if (Eluna* e = player->GetEluna()) + e->OnGiveXP(player, amount, victim); #endif FOREACH_SCRIPT(PlayerScript)->OnGiveXP(player, amount, victim); } @@ -2017,7 +2052,8 @@ void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim) void ScriptMgr::OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental) { #ifdef ELUNA - sEluna->OnReputationChange(player, factionID, standing, incremental); + if (Eluna* e = player->GetEluna()) + e->OnReputationChange(player, factionID, standing, incremental); #endif FOREACH_SCRIPT(PlayerScript)->OnReputationChange(player, factionID, standing, incremental); } @@ -2025,7 +2061,8 @@ void ScriptMgr::OnPlayerReputationChange(Player* player, uint32 factionID, int32 void ScriptMgr::OnPlayerDuelRequest(Player* target, Player* challenger) { #ifdef ELUNA - sEluna->OnDuelRequest(target, challenger); + if (Eluna* e = target->GetEluna()) + e->OnDuelRequest(target, challenger); #endif FOREACH_SCRIPT(PlayerScript)->OnDuelRequest(target, challenger); } @@ -2033,7 +2070,8 @@ void ScriptMgr::OnPlayerDuelRequest(Player* target, Player* challenger) void ScriptMgr::OnPlayerDuelStart(Player* player1, Player* player2) { #ifdef ELUNA - sEluna->OnDuelStart(player1, player2); + if (Eluna* e = player1->GetEluna()) + e->OnDuelStart(player1, player2); #endif FOREACH_SCRIPT(PlayerScript)->OnDuelStart(player1, player2); } @@ -2041,7 +2079,8 @@ void ScriptMgr::OnPlayerDuelStart(Player* player1, Player* player2) void ScriptMgr::OnPlayerDuelEnd(Player* winner, Player* loser, DuelCompleteType type) { #ifdef ELUNA - sEluna->OnDuelEnd(winner, loser, type); + if (Eluna* e = winner->GetEluna()) + e->OnDuelEnd(winner, loser, type); #endif FOREACH_SCRIPT(PlayerScript)->OnDuelEnd(winner, loser, type); } @@ -2074,7 +2113,8 @@ void ScriptMgr::OnPlayerChat(Player* player, uint32 type, uint32 lang, std::stri void ScriptMgr::OnPlayerEmote(Player* player, Emote emote) { #ifdef ELUNA - sEluna->OnEmote(player, emote); + if (Eluna* e = player->GetEluna()) + e->OnEmote(player, emote); #endif FOREACH_SCRIPT(PlayerScript)->OnEmote(player, emote); } @@ -2082,7 +2122,8 @@ void ScriptMgr::OnPlayerEmote(Player* player, Emote emote) void ScriptMgr::OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, ObjectGuid guid) { #ifdef ELUNA - sEluna->OnTextEmote(player, textEmote, emoteNum, guid); + if (Eluna* e = player->GetEluna()) + e->OnTextEmote(player, textEmote, emoteNum, guid); #endif FOREACH_SCRIPT(PlayerScript)->OnTextEmote(player, textEmote, emoteNum, guid); } @@ -2090,7 +2131,8 @@ void ScriptMgr::OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emote void ScriptMgr::OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck) { #ifdef ELUNA - sEluna->OnSpellCast(player, spell, skipCheck); + if (Eluna* e = player->GetEluna()) + e->OnSpellCast(player, spell, skipCheck); #endif FOREACH_SCRIPT(PlayerScript)->OnSpellCast(player, spell, skipCheck); } @@ -2099,8 +2141,8 @@ void ScriptMgr::OnPlayerLogin(Player* player, bool firstLogin) { #ifdef ELUNA if (firstLogin) - sEluna->OnFirstLogin(player); - sEluna->OnLogin(player); + sWorld->GetEluna()->OnFirstLogin(player); + sWorld->GetEluna()->OnLogin(player); #endif FOREACH_SCRIPT(PlayerScript)->OnLogin(player, firstLogin); } @@ -2108,7 +2150,7 @@ void ScriptMgr::OnPlayerLogin(Player* player, bool firstLogin) void ScriptMgr::OnPlayerLogout(Player* player) { #ifdef ELUNA - sEluna->OnLogout(player); + sWorld->GetEluna()->OnLogout(player); #endif FOREACH_SCRIPT(PlayerScript)->OnLogout(player); } @@ -2116,7 +2158,7 @@ void ScriptMgr::OnPlayerLogout(Player* player) void ScriptMgr::OnPlayerCreate(Player* player) { #ifdef ELUNA - sEluna->OnCreate(player); + sWorld->GetEluna()->OnCreate(player); #endif FOREACH_SCRIPT(PlayerScript)->OnCreate(player); } @@ -2124,7 +2166,7 @@ void ScriptMgr::OnPlayerCreate(Player* player) void ScriptMgr::OnPlayerDelete(ObjectGuid guid, uint32 accountId) { #ifdef ELUNA - sEluna->OnDelete(GUID_LOPART(guid)); + sWorld->GetEluna()->OnDelete(GUID_LOPART(guid)); #endif FOREACH_SCRIPT(PlayerScript)->OnDelete(guid, accountId); } @@ -2137,7 +2179,8 @@ void ScriptMgr::OnPlayerFailedDelete(ObjectGuid guid, uint32 accountId) void ScriptMgr::OnPlayerSave(Player* player) { #ifdef ELUNA - sEluna->OnSave(player); + if (Eluna* e = player->GetEluna()) + e->OnSave(player); #endif FOREACH_SCRIPT(PlayerScript)->OnSave(player); } @@ -2145,7 +2188,8 @@ void ScriptMgr::OnPlayerSave(Player* player) void ScriptMgr::OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent, uint8 extendState) { #ifdef ELUNA - sEluna->OnBindToInstance(player, difficulty, mapid, permanent); + if (Eluna* e = player->GetEluna()) + e->OnBindToInstance(player, difficulty, mapid, permanent); #endif FOREACH_SCRIPT(PlayerScript)->OnBindToInstance(player, difficulty, mapid, permanent, extendState); } @@ -2153,7 +2197,8 @@ void ScriptMgr::OnPlayerBindToInstance(Player* player, Difficulty difficulty, ui void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea) { #ifdef ELUNA - sEluna->OnUpdateZone(player, newZone, newArea); + if (Eluna* e = player->GetEluna()) + e->OnUpdateZone(player, newZone, newArea); #endif FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea); } @@ -2161,7 +2206,8 @@ void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newAre void ScriptMgr::OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action) { #ifdef ELUNA - sEluna->HandleGossipSelectOption(player, menu_id, sender, action, ""); + if (Eluna* e = player->GetEluna()) + e->HandleGossipSelectOption(player, menu_id, sender, action, ""); #endif FOREACH_SCRIPT(PlayerScript)->OnGossipSelect(player, menu_id, sender, action); } @@ -2169,7 +2215,8 @@ void ScriptMgr::OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, ui 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); + if (Eluna* e = player->GetEluna()) + e->HandleGossipSelectOption(player, menu_id, sender, action, code); #endif FOREACH_SCRIPT(PlayerScript)->OnGossipSelectCode(player, menu_id, sender, action, code); } @@ -2178,8 +2225,11 @@ void ScriptMgr::OnQuestStatusChange(Player* player, uint32 questId) { #ifdef ELUNA // we can potentially add more quest status hooks here later on - QuestStatus qStatus = player->GetQuestStatus(questId); - sEluna->OnQuestStatusChanged(player, questId, qStatus); + if (Eluna* e = player->GetEluna()) + { + QuestStatus qStatus = player->GetQuestStatus(questId); + e->OnQuestStatusChanged(player, questId, qStatus); + } #endif FOREACH_SCRIPT(PlayerScript)->OnQuestStatusChange(player, questId); } @@ -2234,7 +2284,7 @@ void ScriptMgr::OnFailedPasswordChange(uint32 accountId) void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank) { #ifdef ELUNA - sEluna->OnAddMember(guild, player, plRank); + sWorld->GetEluna()->OnAddMember(guild, player, plRank); #endif FOREACH_SCRIPT(GuildScript)->OnAddMember(guild, player, plRank); } @@ -2242,7 +2292,7 @@ void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank) void ScriptMgr::OnGuildRemoveMember(Guild* guild, Player* player, bool isDisbanding, bool isKicked) { #ifdef ELUNA - sEluna->OnRemoveMember(guild, player, isDisbanding); + sWorld->GetEluna()->OnRemoveMember(guild, player, isDisbanding); #endif FOREACH_SCRIPT(GuildScript)->OnRemoveMember(guild, player, isDisbanding, isKicked); } @@ -2250,7 +2300,7 @@ void ScriptMgr::OnGuildRemoveMember(Guild* guild, Player* player, bool isDisband void ScriptMgr::OnGuildMOTDChanged(Guild* guild, const std::string& newMotd) { #ifdef ELUNA - sEluna->OnMOTDChanged(guild, newMotd); + sWorld->GetEluna()->OnMOTDChanged(guild, newMotd); #endif FOREACH_SCRIPT(GuildScript)->OnMOTDChanged(guild, newMotd); } @@ -2258,7 +2308,7 @@ void ScriptMgr::OnGuildMOTDChanged(Guild* guild, const std::string& newMotd) void ScriptMgr::OnGuildInfoChanged(Guild* guild, const std::string& newInfo) { #ifdef ELUNA - sEluna->OnInfoChanged(guild, newInfo); + sWorld->GetEluna()->OnInfoChanged(guild, newInfo); #endif FOREACH_SCRIPT(GuildScript)->OnInfoChanged(guild, newInfo); } @@ -2266,7 +2316,7 @@ void ScriptMgr::OnGuildInfoChanged(Guild* guild, const std::string& newInfo) void ScriptMgr::OnGuildCreate(Guild* guild, Player* leader, const std::string& name) { #ifdef ELUNA - sEluna->OnCreate(guild, leader, name); + sWorld->GetEluna()->OnCreate(guild, leader, name); #endif FOREACH_SCRIPT(GuildScript)->OnCreate(guild, leader, name); } @@ -2274,7 +2324,7 @@ void ScriptMgr::OnGuildCreate(Guild* guild, Player* leader, const std::string& n void ScriptMgr::OnGuildDisband(Guild* guild) { #ifdef ELUNA - sEluna->OnDisband(guild); + sWorld->GetEluna()->OnDisband(guild); #endif FOREACH_SCRIPT(GuildScript)->OnDisband(guild); } @@ -2282,7 +2332,7 @@ void ScriptMgr::OnGuildDisband(Guild* guild) void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair) { #ifdef ELUNA - sEluna->OnMemberWitdrawMoney(guild, player, amount, isRepair); + sWorld->GetEluna()->OnMemberWitdrawMoney(guild, player, amount, isRepair); #endif FOREACH_SCRIPT(GuildScript)->OnMemberWitdrawMoney(guild, player, amount, isRepair); } @@ -2290,7 +2340,7 @@ void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 & void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount) { #ifdef ELUNA - sEluna->OnMemberDepositMoney(guild, player, amount); + sWorld->GetEluna()->OnMemberDepositMoney(guild, player, amount); #endif FOREACH_SCRIPT(GuildScript)->OnMemberDepositMoney(guild, player, amount); } @@ -2299,7 +2349,7 @@ void ScriptMgr::OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool bool isDestBank, uint8 destContainer, uint8 destSlotId) { #ifdef ELUNA - sEluna->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); + sWorld->GetEluna()->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); #endif FOREACH_SCRIPT(GuildScript)->OnItemMove(guild, player, pItem, isSrcBank, srcContainer, srcSlotId, isDestBank, destContainer, destSlotId); } @@ -2307,7 +2357,7 @@ void ScriptMgr::OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool void ScriptMgr::OnGuildEvent(Guild* guild, uint8 eventType, ObjectGuid::LowType playerGuid1, ObjectGuid::LowType playerGuid2, uint8 newRank) { #ifdef ELUNA - sEluna->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); + sWorld->GetEluna()->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); #endif FOREACH_SCRIPT(GuildScript)->OnEvent(guild, eventType, playerGuid1, playerGuid2, newRank); } @@ -2315,7 +2365,7 @@ void ScriptMgr::OnGuildEvent(Guild* guild, uint8 eventType, ObjectGuid::LowType void ScriptMgr::OnGuildBankEvent(Guild* guild, uint8 eventType, uint8 tabId, ObjectGuid::LowType playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) { #ifdef ELUNA - sEluna->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); + sWorld->GetEluna()->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); #endif FOREACH_SCRIPT(GuildScript)->OnBankEvent(guild, eventType, tabId, playerGuid, itemOrMoney, itemStackCount, destTabId); } @@ -2325,7 +2375,7 @@ void ScriptMgr::OnGroupAddMember(Group* group, ObjectGuid guid) { ASSERT(group); #ifdef ELUNA - sEluna->OnAddMember(group, guid); + sWorld->GetEluna()->OnAddMember(group, guid); #endif FOREACH_SCRIPT(GroupScript)->OnAddMember(group, guid); } @@ -2334,7 +2384,7 @@ void ScriptMgr::OnGroupInviteMember(Group* group, ObjectGuid guid) { ASSERT(group); #ifdef ELUNA - sEluna->OnInviteMember(group, guid); + sWorld->GetEluna()->OnInviteMember(group, guid); #endif FOREACH_SCRIPT(GroupScript)->OnInviteMember(group, guid); } @@ -2343,7 +2393,7 @@ void ScriptMgr::OnGroupRemoveMember(Group* group, ObjectGuid guid, RemoveMethod { ASSERT(group); #ifdef ELUNA - sEluna->OnRemoveMember(group, guid, method); + sWorld->GetEluna()->OnRemoveMember(group, guid, method); #endif FOREACH_SCRIPT(GroupScript)->OnRemoveMember(group, guid, method, kicker, reason); } @@ -2352,7 +2402,7 @@ void ScriptMgr::OnGroupChangeLeader(Group* group, ObjectGuid newLeaderGuid, Obje { ASSERT(group); #ifdef ELUNA - sEluna->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); + sWorld->GetEluna()->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); #endif FOREACH_SCRIPT(GroupScript)->OnChangeLeader(group, newLeaderGuid, oldLeaderGuid); } @@ -2361,7 +2411,7 @@ void ScriptMgr::OnGroupDisband(Group* group) { ASSERT(group); #ifdef ELUNA - sEluna->OnDisband(group); + sWorld->GetEluna()->OnDisband(group); #endif FOREACH_SCRIPT(GroupScript)->OnDisband(group); } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 8a674eface..d57f6a536b 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -253,8 +253,14 @@ void WorldSession::SendPacket(WorldPacket const* packet) sScriptMgr->OnPacketSend(this, *packet); #ifdef ELUNA - if (!sEluna->OnPacketSend(this, *packet)) - return; + if (Player* plr = GetPlayer()) + { + if (Eluna* e = plr->GetEluna()) + { + if (!e->OnPacketSend(this, *packet)) + return; + } + } #endif TC_LOG_TRACE("network.opcode", "S->C: {} {}", GetPlayerInfo(), GetOpcodeNameForLogging(static_cast(packet->GetOpcode()))); @@ -335,7 +341,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) { sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA - if (!sEluna->OnPacketReceive(this, *packet)) + if (!sWorld->GetEluna()->OnPacketReceive(this, *packet)) break; #endif opHandle->Call(this, *packet); @@ -355,7 +361,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) // not expected _player or must checked in packet hanlder sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA - if (!sEluna->OnPacketReceive(this, *packet)) + if (!sWorld->GetEluna()->OnPacketReceive(this, *packet)) break; #endif opHandle->Call(this, *packet); @@ -373,7 +379,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) { sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA - if (!sEluna->OnPacketReceive(this, *packet)) + if (!sWorld->GetEluna()->OnPacketReceive(this, *packet)) break; #endif opHandle->Call(this, *packet); @@ -399,7 +405,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) { sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA - if (!sEluna->OnPacketReceive(this, *packet)) + if (!sWorld->GetEluna()->OnPacketReceive(this, *packet)) break; #endif opHandle->Call(this, *packet); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index ecc23ae452..99c757039f 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5061,7 +5061,8 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) #ifdef ELUNA Creature* c = target->ToCreature(); if (c && caster) - sEluna->OnDummyEffect(triggerCaster, GetId(), SpellEffIndex(GetEffIndex()), c); + if(Eluna * e = caster->GetEluna()) + e->OnDummyEffect(triggerCaster, GetId(), SpellEffIndex(GetEffIndex()), c); #endif triggerCaster->CastSpell(target, triggerSpellId, args); TC_LOG_DEBUG("spells.aura.effect", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell {} Trigger {}", GetId(), triggeredSpellInfo->Id); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3b9a8add02..7026532271 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -717,12 +717,15 @@ void Spell::EffectDummy() TC_LOG_DEBUG("spells", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, uint32(effectInfo->EffectIndex)); m_caster->GetMap()->ScriptsStart(sSpellScripts, uint32(m_spellInfo->Id | (effectInfo->EffectIndex << 24)), m_caster, unitTarget); #ifdef ELUNA - if (gameObjTarget) - sEluna->OnDummyEffect(m_caster, m_spellInfo->Id, effectInfo->EffectIndex, gameObjTarget); - else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT) - sEluna->OnDummyEffect(m_caster, m_spellInfo->Id, effectInfo->EffectIndex, unitTarget->ToCreature()); - else if (itemTarget) - sEluna->OnDummyEffect(m_caster, m_spellInfo->Id, effectInfo->EffectIndex, itemTarget); + if (Eluna* e = m_caster->GetEluna()) + { + if (gameObjTarget) + e->OnDummyEffect(m_caster, m_spellInfo->Id, effectInfo->EffectIndex, gameObjTarget); + else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT) + e->OnDummyEffect(m_caster, m_spellInfo->Id, effectInfo->EffectIndex, unitTarget->ToCreature()); + else if (itemTarget) + e->OnDummyEffect(m_caster, m_spellInfo->Id, effectInfo->EffectIndex, itemTarget); + } #endif } @@ -1738,10 +1741,13 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) player->PlayerTalkClass->ClearMenus(); #ifdef ELUNA - if (sEluna->OnGossipHello(player, gameObjTarget)) - return; - if (sEluna->OnGameObjectUse(player, gameObjTarget)) - return; + if (Eluna* e = player->GetEluna()) + { + if (e->OnGossipHello(player, gameObjTarget)) + return; + if (e->OnGameObjectUse(player, gameObjTarget)) + return; + } #endif if (gameObjTarget->AI()->OnGossipHello(player)) return; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index d99b643af7..ed5308c9df 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -88,6 +88,7 @@ #include "WeatherMgr.h" #ifdef ELUNA #include "LuaEngine.h" +#include "ElunaLoader.h" #endif #include "WhoListStorage.h" #include "WorldSession.h" @@ -153,6 +154,12 @@ World::World() /// World destructor World::~World() { +#ifdef ELUNA + // Delete world Eluna state + delete eluna; + eluna = nullptr; +#endif + ///- Empty the kicked session set while (!m_sessions.empty()) { @@ -1599,8 +1606,8 @@ void World::SetInitialWorldSettings() #ifdef ELUNA ///- Initialize Lua Engine - TC_LOG_INFO("server.loading", "Initialize Eluna Lua Engine..."); - Eluna::Initialize(); + TC_LOG_INFO("server.loading", "Loading Lua scripts..."); + sElunaLoader->LoadScripts(); #endif ///- Initialize pool manager @@ -2087,6 +2094,13 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Creature Text Locales..."); sCreatureTextMgr->LoadCreatureTextLocales(); +#ifdef ELUNA + TC_LOG_INFO("server.loading", "Starting Eluna world state..."); + // use map id -1 for the global Eluna state + bool compatMode = sConfigMgr->GetBoolDefault("Eluna.CompatibilityMode", true); + eluna = new Eluna(nullptr, compatMode); +#endif + TC_LOG_INFO("server.loading", "Initializing Scripts..."); sScriptMgr->Initialize(); sScriptMgr->OnConfigLoad(false); // must be done after the ScriptMgr has been properly initialized @@ -2222,10 +2236,7 @@ void World::SetInitialWorldSettings() InitGuildResetTime(); #ifdef ELUNA - ///- Run eluna scripts. - // in multithread foreach: run scripts - sEluna->RunScripts(); - sEluna->OnConfigLoad(false); // Must be done after Eluna is initialized and scripts have run. + eluna->OnConfigLoad(false); // Must be done after Eluna is initialized and scripts have run. #endif // Preload all cells, if required for the base maps diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 62caaefc12..e288f0df6a 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -35,6 +35,9 @@ #include #include +#ifdef ELUNA +class Eluna; +#endif class Player; class WorldPacket; class WorldSession; @@ -771,6 +774,10 @@ class TC_GAME_API World bool IsGuidWarning() { return _guidWarn; } bool IsGuidAlert() { return _guidAlert; } +#ifdef ELUNA + Eluna* GetEluna() const { return eluna; } + Eluna* eluna; +#endif protected: void _UpdateGameTime(); diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 118f8fad43..69689362a6 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -315,9 +315,6 @@ extern int main(int argc, char** argv) sInstanceSaveMgr->Unload(); sOutdoorPvPMgr->Die(); // unload it before MapManager sMapMgr->UnloadAll(); // unload all grids (including locked in memory) -#ifdef ELUNA - Eluna::Uninitialize(); -#endif }); // Start the Remote Access port (acceptor) if enabled diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 794603cd00..58ca194a57 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -3867,22 +3867,36 @@ AuctionHouseBot.Buyer.Recheck.Interval = 20 # # Eluna.Enabled # Description: Enable or disable Eluna LuaEngine -# Default: true - (enabled) -# false - (disabled) +# Default: true - (enabled) +# false - (disabled) +# +# Eluna.CompatibilityMode +# Description: Toggles Eluna between compatibility mode (single-threaded) or multistate mode. +# Compatibility mode limits the core to a single map update thread. +# Default: true - (enabled) +# false - (disabled) +# +# Eluna.OnlyOnMaps +# Description: When Eluna is enabled, a state will only be created for a list of specified maps +# This only works for multistate mode. +# Default: "" - (enabled on all maps) +# "0,1,2,..." - (enabled on specific maps only) # # Eluna.TraceBack # Description: Sets whether to use debug.traceback function on a lua error or not. # Notice that you can redefine the function. -# Default: false - (use default error output) -# true - (use debug.traceback function) +# Default: false - (use default error output) +# true - (use debug.traceback function) # # Eluna.ScriptPath # Description: Sets the location of the script folder to load scripts from # The path can be relative or absolute. -# Default: "lua_scripts" +# Default: "lua_scripts" # Eluna.Enabled = true +Eluna.CompatibilityMode = true +Eluna.OnlyOnMaps = "" Eluna.TraceBack = false Eluna.ScriptPath = "lua_scripts"