diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 4d47cb7fd..93ecac1ac 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -3087,3 +3087,111 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh) MANGOS_ASSERT(0); return 0; } + +/** + * Helper structure for building static chat information + * + */ +class StaticMonsterChatBuilder +{ + public: + StaticMonsterChatBuilder(CreatureInfo const* cInfo, ChatMsg msgtype, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0) + : i_cInfo(cInfo), i_msgtype(msgtype), i_textId(textId), i_language(language), i_target(target) + { + // 0 lowguid not used in core, but accepted fine in this case by client + i_senderGuid = i_cInfo->GetObjectGuid(senderLowGuid); + } + void operator()(WorldPacket& data, int32 loc_idx) + { + char const* text = sObjectMgr.GetMangosString(i_textId,loc_idx); + + std::string nameForLocale = ""; + if (loc_idx >= 0) + { + CreatureLocale const *cl = sObjectMgr.GetCreatureLocale(i_cInfo->Entry); + if (cl) + { + if (cl->Name.size() > (size_t)loc_idx && !cl->Name[loc_idx].empty()) + nameForLocale = cl->Name[loc_idx]; + } + } + + if (nameForLocale.empty()) + nameForLocale = i_cInfo->Name; + + WorldObject::BuildMonsterChat(&data, i_senderGuid, i_msgtype, text, i_language, nameForLocale.c_str(), i_target ? i_target->GetObjectGuid() : ObjectGuid(), i_target ? i_target->GetNameForLocaleIdx(loc_idx) : ""); + } + + private: + ObjectGuid i_senderGuid; + CreatureInfo const* i_cInfo; + ChatMsg i_msgtype; + int32 i_textId; + uint32 i_language; + Unit* i_target; +}; + + +/** + * Function simulates yell of creature + * + * @param guid must be creature guid of whom to Simulate the yell, non-creature guids not supported at this moment + * @param textId Id of the simulated text + * @param language language of the text + * @param target, can be NULL + */ +void Map::MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit* target) +{ + if (guid.IsAnyTypeCreature()) + { + CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(guid.GetEntry()); + if (!cInfo) + { + sLog.outError("Map::MonsterYellToMap: Called for nonexistent creature entry in guid: %s", guid.GetString().c_str()); + return; + } + + MonsterYellToMap(cInfo, textId, language, target, guid.GetCounter()); + } + else + { + sLog.outError("Map::MonsterYellToMap: Called for non creature guid: %s", guid.GetString().c_str()); + return; + } +} + + +/** + * Function simulates yell of creature + * + * @param cinfo must be entry of Creature of whom to Simulate the yell + * @param textId Id of the simulated text + * @param language language of the text + * @param target, can be NULL + * @param senderLowGuid provide way proper show yell for near spawned creature with known lowguid, + * 0 accepted by client else if this not important + */ +void Map::MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid /*= 0*/) +{ + StaticMonsterChatBuilder say_build(cinfo, CHAT_MSG_MONSTER_YELL, textId, language, target, senderLowGuid); + MaNGOS::LocalizedPacketDo say_do(say_build); + + Map::PlayerList const& pList = GetPlayers(); + for (PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) + say_do(itr->getSource()); +} + +/** + * Function to play sound to all players in map + * + * @param soundId Played Sound + */ +void Map::PlayDirectSoundToMap(uint32 soundId) +{ + WorldPacket data(SMSG_PLAY_SOUND, 4); + data << uint32(soundId); + + Map::PlayerList const& pList = GetPlayers(); + for (PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr) + itr->getSource()->SendDirectMessage(&data); +} diff --git a/src/game/Map.h b/src/game/Map.h index 3dde4d9a9..31e8731cb 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -40,6 +40,7 @@ #include #include +struct CreatureInfo; class Creature; class Unit; class WorldPacket; @@ -94,6 +95,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager friend class MapReference; friend class ObjectGridLoader; friend class ObjectWorldLoader; + protected: Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode); @@ -252,6 +254,11 @@ class MANGOS_DLL_SPEC Map : public GridRefManager void CreateInstanceData(bool load); InstanceData* GetInstanceData() { return i_data; } uint32 GetScriptId() const { return i_script_id; } + + void MonsterYellToMap(ObjectGuid guid, int32 textId, uint32 language, Unit* target); + void MonsterYellToMap(CreatureInfo const* cinfo, int32 textId, uint32 language, Unit* target, uint32 senderLowGuid = 0); + void PlayDirectSoundToMap(uint32 soundId); + private: void LoadMapAndVMap(int gx, int gy); @@ -289,8 +296,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager void SendObjectUpdates(); std::set i_objectsToClientUpdate; - protected: + protected: MapEntry const* i_mapEntry; uint8 i_spawnMode; uint32 i_id; @@ -306,6 +313,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager ActiveNonPlayers m_activeNonPlayers; ActiveNonPlayers::iterator m_activeNonPlayersIter; MapStoredObjectTypesContainer m_objectsStore; + private: time_t i_gridExpiry; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index c0cb288a9..318cd373f 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1471,21 +1471,21 @@ bool WorldObject::IsPositionValid() const void WorldObject::MonsterSay(const char* text, uint32 language, Unit* target) { WorldPacket data(SMSG_MESSAGECHAT, 200); - BuildMonsterChat(&data, CHAT_MSG_MONSTER_SAY, text, language, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : ""); + BuildMonsterChat(&data, GetObjectGuid(), CHAT_MSG_MONSTER_SAY, text, language, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : ""); SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_SAY),true); } void WorldObject::MonsterYell(const char* text, uint32 language, Unit* target) { WorldPacket data(SMSG_MESSAGECHAT, 200); - BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, text, language, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : ""); + BuildMonsterChat(&data, GetObjectGuid(), CHAT_MSG_MONSTER_YELL, text, language, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : ""); SendMessageToSetInRange(&data,sWorld.getConfig(CONFIG_FLOAT_LISTEN_RANGE_YELL),true); } void WorldObject::MonsterTextEmote(const char* text, Unit* target, bool IsBossEmote) { WorldPacket data(SMSG_MESSAGECHAT, 200); - BuildMonsterChat(&data, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, text, LANG_UNIVERSAL, + BuildMonsterChat(&data, GetObjectGuid(), IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, text, LANG_UNIVERSAL, GetName(), target ? target->GetObjectGuid() : ObjectGuid(), target ? target->GetName() : ""); SendMessageToSetInRange(&data, sWorld.getConfig(IsBossEmote ? CONFIG_FLOAT_LISTEN_RANGE_YELL : CONFIG_FLOAT_LISTEN_RANGE_TEXTEMOTE), true); } @@ -1496,7 +1496,7 @@ void WorldObject::MonsterWhisper(const char* text, Unit* target, bool IsBossWhis return; WorldPacket data(SMSG_MESSAGECHAT, 200); - BuildMonsterChat(&data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, + BuildMonsterChat(&data, GetObjectGuid(), IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, GetName(), target->GetObjectGuid(), target->GetName()); ((Player*)target)->GetSession()->SendPacket(&data); } @@ -1512,7 +1512,7 @@ namespace MaNGOS { char const* text = sObjectMgr.GetMangosString(i_textId,loc_idx); - i_object.BuildMonsterChat(&data, i_msgtype, text, i_language, i_object.GetNameForLocaleIdx(loc_idx), i_target ? i_target->GetObjectGuid() : ObjectGuid(), i_target ? i_target->GetNameForLocaleIdx(loc_idx) : ""); + WorldObject::BuildMonsterChat(&data, i_object.GetObjectGuid(), i_msgtype, text, i_language, i_object.GetNameForLocaleIdx(loc_idx), i_target ? i_target->GetObjectGuid() : ObjectGuid(), i_target ? i_target->GetNameForLocaleIdx(loc_idx) : ""); } private: @@ -1574,17 +1574,17 @@ void WorldObject::MonsterWhisper(int32 textId, Unit* target, bool IsBossWhisper) char const* text = sObjectMgr.GetMangosString(textId, loc_idx); WorldPacket data(SMSG_MESSAGECHAT, 200); - BuildMonsterChat(&data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, + BuildMonsterChat(&data, GetObjectGuid(), IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, GetNameForLocaleIdx(loc_idx), target->GetObjectGuid(), ""); ((Player*)target)->GetSession()->SendPacket(&data); } -void WorldObject::BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, ObjectGuid targetGuid, char const* targetName) const +void WorldObject::BuildMonsterChat(WorldPacket *data, ObjectGuid senderGuid, uint8 msgtype, char const* text, uint32 language, char const* name, ObjectGuid targetGuid, char const* targetName) { *data << uint8(msgtype); *data << uint32(language); - *data << ObjectGuid(GetObjectGuid()); + *data << ObjectGuid(senderGuid); *data << uint32(0); // 2.1.0 *data << uint32(strlen(name)+1); *data << name; diff --git a/src/game/Object.h b/src/game/Object.h index 5108f7bd8..acc62e520 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -542,7 +542,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object void MonsterTextEmote(int32 textId, Unit* target, bool IsBossEmote = false); void MonsterWhisper(int32 textId, Unit* receiver, bool IsBossWhisper = false); void MonsterYellToZone(int32 textId, uint32 language, Unit* target); - void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* text, uint32 language, char const* name, ObjectGuid targetGuid, char const* targetName) const; + static void BuildMonsterChat(WorldPacket *data, ObjectGuid senderGuid, uint8 msgtype, char const* text, uint32 language, char const* name, ObjectGuid targetGuid, char const* targetName); void PlayDistanceSound(uint32 sound_id, Player* target = NULL); void PlayDirectSound(uint32 sound_id, Player* target = NULL); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8bcb6beed..c5b8277b2 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 "11574" + #define REVISION_NR "11575" #endif // __REVISION_NR_H__