diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index a000dd927..7078bea9d 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -479,6 +479,26 @@ namespace MaNGOS template void Visit(GridRefManager &) {} }; + template + struct MANGOS_DLL_DECL PlayerDistWorker + { + WorldObject const* i_searcher; + float i_dist; + Do& i_do; + + PlayerDistWorker(WorldObject const* searcher, float _dist, Do& _do) + : i_searcher(searcher), i_dist(_dist), i_do(_do) {} + + void Visit(PlayerMapType &m) + { + for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) + if(itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->GetDistance(i_searcher) <= i_dist) + i_do(itr->getSource()); + } + + template void Visit(GridRefManager &) {} + }; + // CHECKS && DO classes // WorldObject check classes @@ -819,6 +839,28 @@ namespace MaNGOS float i_range; }; + // Player checks and do + + // Prepare using Builder localized packets with caching and send to player + template + class LocalizedPacketDo + { + public: + explicit LocalizedPacketDo(Builder& builder) : i_builder(builder) {} + + LocalizedPacketDo::~LocalizedPacketDo() + { + for(int i = 0; i < i_data_cache.size(); ++i) + delete i_data_cache[i]; + } + void operator()( Player* p ); + + private: + Builder& i_builder; + std::vector i_data_cache; // 0 = default, i => i-1 locale index + }; + + #ifndef WIN32 template<> void PlayerRelocationNotifier::Visit(CreatureMapType &); template<> void PlayerRelocationNotifier::Visit(PlayerMapType &); diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index d0815bc35..6903fa23d 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -537,4 +537,29 @@ void MaNGOS::PlayerSearcher::Visit(PlayerMapType &m) } } +template +void MaNGOS::LocalizedPacketDo::operator()( Player* p ) +{ + uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); + uint32 cache_idx = loc_idx+1; + WorldPacket* data; + + // create if not cached yet + if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx]) + { + if(i_data_cache.size() < cache_idx+1) + i_data_cache.resize(cache_idx+1); + + data = new WorldPacket(SMSG_MESSAGECHAT, 200); + + i_builder(*data,loc_idx); + + i_data_cache[cache_idx] = data; + } + else + data = i_data_cache[cache_idx]; + + p->SendDirectMessage(data); +} + #endif // MANGOS_GRIDNOTIFIERSIMPL_H diff --git a/src/game/Guild.h b/src/game/Guild.h index d1c1e322e..c8bf2a809 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -315,6 +315,14 @@ class Guild void BroadcastPacketToRank(WorldPacket *packet, uint32 rankId); void BroadcastPacket(WorldPacket *packet); + template + void BroadcastWorker(Do& _do) + { + for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr) + if(Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) + _do(player); + } + void CreateRank(std::string name,uint32 rights); void DelRank(); std::string GetRankName(uint32 rankId); diff --git a/src/game/Object.cpp b/src/game/Object.cpp index a132742a5..29039ecfc 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1246,50 +1246,17 @@ void WorldObject::MonsterWhisper(const char* text, uint64 receiver, bool IsBossW namespace MaNGOS { - class MessageChatLocaleCacheDo + class MonsterChatBuilder { public: - MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist) - : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), - i_targetGUID(targetGUID), i_dist(dist) + MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID) + : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_targetGUID(targetGUID) {} + void operator()(WorldPacket& data, int32 loc_idx) { - } + char const* text = objmgr.GetMangosString(i_textId,loc_idx); - ~MessageChatLocaleCacheDo() - { - for(int i = 0; i < i_data_cache.size(); ++i) - delete i_data_cache[i]; - } - - void operator()(Player* p) - { - // skip far away players - if(p->GetDistance(&i_object) > i_dist) - return; - - uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); - uint32 cache_idx = loc_idx+1; - WorldPacket* data; - - // create if not cached yet - if(i_data_cache.size() < cache_idx+1 || !i_data_cache[cache_idx]) - { - if(i_data_cache.size() < cache_idx+1) - i_data_cache.resize(cache_idx+1); - - char const* text = objmgr.GetMangosString(i_textId,loc_idx); - - data = new WorldPacket(SMSG_MESSAGECHAT, 200); - - // TODO: i_object.GetName() also must be localized? - i_object.BuildMonsterChat(data,i_msgtype,text,i_language,i_object.GetNameForLocaleIdx(loc_idx),i_targetGUID); - - i_data_cache[cache_idx] = data; - } - else - data = i_data_cache[cache_idx]; - - p->SendDirectMessage(data); + // TODO: i_object.GetName() also must be localized? + i_object.BuildMonsterChat(&data,i_msgtype,text,i_language,i_object.GetNameForLocaleIdx(loc_idx),i_targetGUID); } private: @@ -1298,8 +1265,6 @@ namespace MaNGOS int32 i_textId; uint32 i_language; uint64 i_targetGUID; - float i_dist; - std::vector i_data_cache; // 0 = default, i => i-1 locale index }; } // namespace MaNGOS @@ -1311,9 +1276,10 @@ void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid) cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY)); - MaNGOS::PlayerWorker say_worker(this,say_do); - TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); + MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId,language,TargetGuid); + MaNGOS::LocalizedPacketDo say_do(say_build); + MaNGOS::PlayerDistWorker > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do); + TypeContainerVisitor >, WorldTypeMapContainer > message(say_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetMap()); } @@ -1326,9 +1292,10 @@ void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid) cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::MessageChatLocaleCacheDo say_do(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL)); - MaNGOS::PlayerWorker say_worker(this,say_do); - TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); + MaNGOS::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId,language,TargetGuid); + MaNGOS::LocalizedPacketDo say_do(say_build); + MaNGOS::PlayerDistWorker > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL),say_do); + TypeContainerVisitor >, WorldTypeMapContainer > message(say_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetMap()); } @@ -1341,9 +1308,10 @@ void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossE cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::MessageChatLocaleCacheDo say_do(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - MaNGOS::PlayerWorker say_worker(this,say_do); - TypeContainerVisitor, WorldTypeMapContainer > message(say_worker); + MaNGOS::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId,LANG_UNIVERSAL,TargetGuid); + MaNGOS::LocalizedPacketDo say_do(say_build); + MaNGOS::PlayerDistWorker > say_worker(this,sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),say_do); + TypeContainerVisitor >, WorldTypeMapContainer > message(say_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetMap()); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1f3088c2e..5990b611d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7310" + #define REVISION_NR "7311" #endif // __REVISION_NR_H__