Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
CreatureTextMgr.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Cell.h"
7#include "CellImpl.h"
8#include "Chat.h"
9#include "Common.h"
10#include "CreatureTextMgr.h"
11#include "DatabaseEnv.h"
12#include "GridNotifiers.h"
13#include "GridNotifiersImpl.h"
14#include "ObjectMgr.h"
15
17{
18public:
19 CreatureTextBuilder(WorldObject* obj, ChatMsg msgtype, uint8 textGroup, uint32 id, Language language, WorldObject const* target)
20 : _source(obj), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target)
21 {
22 }
23
24 size_t operator()(WorldPacket* data, LocaleConstant locale) const
25 {
26 std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _textGroup, _textId, locale);
27 return ChatHandler::BuildChatPacket(*data, _msgType, _language, _source, _target, text, 0, "", locale);;
28 }
29
36};
37
39{
40public:
41 PlayerTextBuilder(WorldObject* obj, WorldObject* speaker, ChatMsg msgtype, uint8 textGroup, uint32 id, Language language, WorldObject const* target)
42 : _source(obj), _talker(speaker), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { }
43
44 size_t operator()(WorldPacket* data, LocaleConstant locale) const
45 {
46 std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _textGroup, _textId, locale);
47 return ChatHandler::BuildChatPacket(*data, _msgType, _language, _talker, _target, text, 0, "", locale);
48 }
49
57};
58
60{
61 uint32 oldMSTime = getMSTime();
62
63 mTextMap.clear(); // for reload case
64 mTextRepeatMap.clear(); //reset all currently used temp texts
65
66 PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEXT);
67 PreparedQueryResult result = WorldDatabase.Query(stmt);
68
69 if (!result)
70 {
71 SF_LOG_INFO("server.loading", ">> Loaded 0 ceature texts. DB table `creature_texts` is empty.");
72
73 return;
74 }
75
76 uint32 textCount = 0;
77 uint32 creatureCount = 0;
78
79 do
80 {
81 Field* fields = result->Fetch();
83
84 temp.entry = fields[0].GetUInt32();
85 temp.group = fields[1].GetUInt8();
86 temp.id = fields[2].GetUInt8();
87 temp.text = fields[3].GetString();
88 temp.type = ChatMsg(fields[4].GetUInt8());
89 temp.lang = Language(fields[5].GetUInt8());
90 temp.probability = fields[6].GetFloat();
91 temp.emote = Emote(fields[7].GetUInt32());
92 temp.duration = fields[8].GetUInt32();
93 temp.sound = fields[9].GetUInt32();
94
95 if (temp.sound)
96 {
97 if (!sSoundEntriesStore.LookupEntry(temp.sound)) {
98 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Sound %u but sound does not exist.", temp.entry, temp.group, temp.sound);
99 temp.sound = 0;
100 }
101 }
102 if (!GetLanguageDescByID(temp.lang))
103 {
104 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_texts` using Language %u but Language does not exist.", temp.entry, temp.group, uint32(temp.lang));
106 }
107 if (temp.type >= ChatMsg::MSG_NULL_ACTION)
108 {
109 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Type %u but this Chat Type does not exist.", temp.entry, temp.group, uint32(temp.type));
111 }
112 if (temp.emote)
113 {
114 if (!sEmotesStore.LookupEntry(temp.emote))
115 {
116 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Emote %u but emote does not exist.", temp.entry, temp.group, uint32(temp.emote));
118 }
119 }
120 //entry not yet added, add empty TextHolder (list of groups)
121 if (mTextMap.find(temp.entry) == mTextMap.end())
122 ++creatureCount;
123
124 //add the text into our entry's group
125 mTextMap[temp.entry][temp.group].push_back(temp);
126
127 ++textCount;
128 } while (result->NextRow());
129
130 SF_LOG_INFO("server.loading", ">> Loaded %u creature texts for %u creatures in %u ms", textCount, creatureCount, GetMSTimeDiffToNow(oldMSTime));
131}
132
134{
135 uint32 oldMSTime = getMSTime();
136
137 mLocaleTextMap.clear(); // for reload case
138
139 QueryResult result = WorldDatabase.Query("SELECT entry, groupid, id, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8, text_loc9, text_loc10, text_loc11 FROM locales_creature_text");
140
141 if (!result)
142 return;
143
144 uint32 textCount = 0;
145
146 do
147 {
148 Field* fields = result->Fetch();
149 CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), uint32(fields[2].GetUInt8()))];
150 for (uint8 i = 1; i < TOTAL_LOCALES; ++i)
151 {
152 LocaleConstant locale = LocaleConstant(i);
153 ObjectMgr::AddLocaleString(fields[3 + i - 1].GetString(), locale, loc.Text);
154 }
155
156 ++textCount;
157 } while (result->NextRow());
158
159 SF_LOG_INFO("server.loading", ">> Loaded %u creature localized texts in %u ms", textCount, GetMSTimeDiffToNow(oldMSTime));
160}
161
162uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject const* whisperTarget /*= NULL*/, ChatMsg msgType /*= CHAT_MSG_ADDON*/, Language language /*= LANG_ADDON*/, CreatureTextRange range /*= TEXT_RANGE_NORMAL*/, uint32 sound /*= 0*/, Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/, Player* srcPlr /*= NULL*/)
163{
164 if (!source)
165 return 0;
166
167 CreatureTextMap::const_iterator sList = mTextMap.find(source->GetEntry());
168 if (sList == mTextMap.end())
169 {
170 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: Could not find Text for Creature(%s) Entry %u in 'creature_text' table. Ignoring.", source->GetName().c_str(), source->GetEntry());
171 return 0;
172 }
173
174 CreatureTextHolder const& textHolder = sList->second;
175 CreatureTextHolder::const_iterator itr = textHolder.find(textGroup);
176 if (itr == textHolder.end())
177 {
178 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: Could not find TextGroup %u for Creature(%s) GuidLow %u Entry %u. Ignoring.", uint32(textGroup), source->GetName().c_str(), source->GetGUIDLow(), source->GetEntry());
179 return 0;
180 }
181
182 CreatureTextGroup const& textGroupContainer = itr->second; //has all texts in the group
183 CreatureTextRepeatIds repeatGroup = GetRepeatGroup(source, textGroup);//has all textIDs from the group that were already said
184 CreatureTextGroup tempGroup;//will use this to talk after sorting repeatGroup
185
186 for (CreatureTextGroup::const_iterator giter = textGroupContainer.begin(); giter != textGroupContainer.end(); ++giter)
187 if (std::find(repeatGroup.begin(), repeatGroup.end(), giter->id) == repeatGroup.end())
188 tempGroup.push_back(*giter);
189
190 if (tempGroup.empty())
191 {
192 CreatureTextRepeatMap::iterator mapItr = mTextRepeatMap.find(source->GetGUID());
193 if (mapItr != mTextRepeatMap.end())
194 {
195 CreatureTextRepeatGroup::iterator groupItr = mapItr->second.find(textGroup);
196 groupItr->second.clear();
197 }
198
199 tempGroup = textGroupContainer;
200 }
201
202 uint8 count = 0;
203 float lastChance = -1;
204 bool isEqualChanced = true;
205
206 float totalChance = 0;
207
208 for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
209 {
210 if (lastChance >= 0 && lastChance != iter->probability)
211 isEqualChanced = false;
212
213 lastChance = iter->probability;
214 totalChance += iter->probability;
215 ++count;
216 }
217
218 int32 offset = -1;
219 if (!isEqualChanced)
220 {
221 for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
222 {
223 uint32 chance = uint32(iter->probability);
224 uint32 r = std::rand() % 100;
225 ++offset;
226 if (r <= chance)
227 break;
228 }
229 }
230
231 uint32 pos = 0;
232 if (isEqualChanced || offset < 0)
233 pos = std::rand() % count;
234 else if (offset >= 0)
235 pos = offset;
236
237 CreatureTextGroup::const_iterator iter = tempGroup.begin() + pos;
238
239 ChatMsg finalType = (msgType == ChatMsg::CHAT_MSG_ADDON) ? iter->type : msgType;
240 Language finalLang = (language == Language::LANG_ADDON) ? iter->lang : language;
241 uint32 finalSound = sound ? sound : iter->sound;
242
243 if (finalSound)
244 SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly);
245
246 Unit* finalSource = source;
247 if (srcPlr)
248 finalSource = srcPlr;
249
250 if (iter->emote)
251 SendEmote(finalSource, iter->emote);
252
253 if (srcPlr)
254 {
255 PlayerTextBuilder builder(source, finalSource, finalType, iter->group, iter->id, finalLang, whisperTarget);
256 SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
257 }
258 else
259 {
260 CreatureTextBuilder builder(finalSource, finalType, iter->group, iter->id, finalLang, whisperTarget);
261 SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
262 }
263 if (isEqualChanced || (!isEqualChanced && totalChance == 100.0f))
264 SetRepeatId(source, textGroup, iter->id);
265
266 return iter->duration;
267}
268
270{
271 float dist = sWorld->GetFloatConfig(WorldFloatConfigs::CONFIG_LISTEN_RANGE_SAY);
272 switch (msgType)
273 {
276 break;
280 break;
281 default:
282 break;
283 }
284
285 return dist;
286}
287
288void CreatureTextMgr::SendSound(Creature* source, uint32 sound, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly)
289{
290 if (!sound || !source)
291 return;
292
293 ObjectGuid guid = source->GetGUID();
294
295 WorldPacket data(SMSG_PLAY_SOUND, 4 + 9);
296 data.WriteBit(guid[2]);
297 data.WriteBit(guid[3]);
298 data.WriteBit(guid[7]);
299 data.WriteBit(guid[6]);
300 data.WriteBit(guid[0]);
301 data.WriteBit(guid[5]);
302 data.WriteBit(guid[4]);
303 data.WriteBit(guid[1]);
304
305 data << uint32(sound);
306 data.WriteByteSeq(guid[3]);
307 data.WriteByteSeq(guid[2]);
308 data.WriteByteSeq(guid[4]);
309 data.WriteByteSeq(guid[7]);
310 data.WriteByteSeq(guid[5]);
311 data.WriteByteSeq(guid[0]);
312 data.WriteByteSeq(guid[6]);
313 data.WriteByteSeq(guid[1]);
314 SendNonChatPacket(source, &data, msgType, whisperTarget, range, team, gmOnly);
315}
316
317void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const
318{
319 float dist = GetRangeForChatType(msgType);
320
321 switch (msgType)
322 {
325 {
326 if (range == TEXT_RANGE_NORMAL)//ignores team and gmOnly
327 {
328 if (!whisperTarget || whisperTarget->GetTypeId() != TypeID::TYPEID_PLAYER)
329 return;
330
331 whisperTarget->ToPlayer()->GetSession()->SendPacket(data);
332 return;
333 }
334 break;
335 }
336 default:
337 break;
338 }
339
340 switch (range)
341 {
342 case TEXT_RANGE_AREA:
343 {
344 uint32 areaId = source->GetAreaId();
345 Map::PlayerList const& players = source->GetMap()->GetPlayers();
346 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
347 if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
348 itr->GetSource()->GetSession()->SendPacket(data);
349 return;
350 }
351 case TEXT_RANGE_ZONE:
352 {
353 uint32 zoneId = source->GetZoneId();
354 Map::PlayerList const& players = source->GetMap()->GetPlayers();
355 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
356 if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
357 itr->GetSource()->GetSession()->SendPacket(data);
358 return;
359 }
360 case TEXT_RANGE_MAP:
361 {
362 Map::PlayerList const& players = source->GetMap()->GetPlayers();
363 for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
364 if ((!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
365 itr->GetSource()->GetSession()->SendPacket(data);
366 return;
367 }
368 case TEXT_RANGE_WORLD:
369 {
370 SessionMap const& smap = sWorld->GetAllSessions();
371 for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter)
372 if (Player* player = iter->second->GetPlayer())
373 if (player->GetSession() && (!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster()))
374 player->GetSession()->SendPacket(data);
375 return;
376 }
378 default:
379 break;
380 }
381
382 source->SendMessageToSetInRange(data, dist, true);
383}
384
386{
387 if (!source)
388 return;
389
390 source->HandleEmoteCommand(emote);
391}
392
394{
395 if (!source)
396 return;
397
398 CreatureTextRepeatIds& repeats = mTextRepeatMap[source->GetGUID()][textGroup];
399 if (std::find(repeats.begin(), repeats.end(), id) == repeats.end())
400 repeats.push_back(id);
401 else
402 SF_LOG_ERROR("sql.sql", "CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), source->GetName().c_str(), source->GetGUIDLow(), source->GetEntry(), uint32(id));
403}
404
406{
407 ASSERT(source);//should never happen
409
410 CreatureTextRepeatMap::const_iterator mapItr = mTextRepeatMap.find(source->GetGUID());
411 if (mapItr != mTextRepeatMap.end())
412 {
413 CreatureTextRepeatGroup::const_iterator groupItr = (*mapItr).second.find(textGroup);
414 if (groupItr != mapItr->second.end())
415 ids = groupItr->second;
416 }
417 return ids;
418}
419
420bool CreatureTextMgr::TextExist(uint32 sourceEntry, uint8 textGroup)
421{
422 if (!sourceEntry)
423 return false;
424
425 CreatureTextMap::const_iterator sList = mTextMap.find(sourceEntry);
426 if (sList == mTextMap.end())
427 {
428 SF_LOG_DEBUG("entities.unit", "CreatureTextMgr::TextExist: Could not find Text for Creature (entry %u) in 'creature_text' table.", sourceEntry);
429 return false;
430 }
431
432 CreatureTextHolder const& textHolder = sList->second;
433 CreatureTextHolder::const_iterator itr = textHolder.find(textGroup);
434 if (itr == textHolder.end())
435 {
436 SF_LOG_DEBUG("entities.unit", "CreatureTextMgr::TextExist: Could not find TextGroup %u for Creature (entry %u).", uint32(textGroup), sourceEntry);
437 return false;
438 }
439
440 return true;
441}
442
443std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 textGroup, uint32 id, LocaleConstant locale) const
444{
445 CreatureTextMap::const_iterator mapitr = mTextMap.find(entry);
446 if (mapitr == mTextMap.end())
447 return "";
448
449 CreatureTextHolder::const_iterator holderItr = mapitr->second.find(textGroup);
450 if (holderItr == mapitr->second.end())
451 return "";
452
453 CreatureTextGroup::const_iterator groupItr = holderItr->second.begin();
454 for (; groupItr != holderItr->second.end(); ++groupItr)
455 if (groupItr->id == id)
456 break;
457
458 if (groupItr == holderItr->second.end())
459 return "";
460
461 std::string baseText = groupItr->text;
462 if (locale == DEFAULT_LOCALE)
463 return baseText;
464
465 if (locale > MAX_LOCALES)
466 return baseText;
467
468 LocaleCreatureTextMap::const_iterator locItr = mLocaleTextMap.find(CreatureTextId(entry, uint32(textGroup), id));
469 if (locItr == mLocaleTextMap.end())
470 return baseText;
471
472 ObjectMgr::GetLocaleString(locItr->second.Text, locale, baseText);
473
474 return baseText;
475}
const uint8 TOTAL_LOCALES
Definition Common.h:153
LocaleConstant
Definition Common.h:138
#define DEFAULT_LOCALE
Definition Common.h:154
#define MAX_LOCALES
Definition Common.h:156
#define sCreatureTextMgr
std::vector< uint8 > CreatureTextRepeatIds
UNORDERED_MAP< uint8, CreatureTextGroup > CreatureTextHolder
std::vector< CreatureTextEntry > CreatureTextGroup
CreatureTextRange
@ TEXT_RANGE_ZONE
@ TEXT_RANGE_AREA
@ TEXT_RANGE_WORLD
@ TEXT_RANGE_NORMAL
@ TEXT_RANGE_MAP
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
DBCStorage< EmotesEntry > sEmotesStore(EmotesEntryfmt)
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define ASSERT
Definition Errors.h:29
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
@ TYPEID_PLAYER
Definition Object.h:55
LanguageDesc const * GetLanguageDescByID(Language lang)
Skyfire::AutoPtr< PreparedResultSet, Skyfire::Mutex > PreparedQueryResult
Definition QueryResult.h:94
Skyfire::AutoPtr< ResultSet, Skyfire::Mutex > QueryResult
Definition QueryResult.h:48
@ EMOTE_ONESHOT_NONE
ChatMsg
@ CHAT_MSG_MONSTER_EMOTE
@ CHAT_MSG_RAID_BOSS_WHISPER
@ CHAT_MSG_RAID_BOSS_EMOTE
@ CHAT_MSG_MONSTER_YELL
@ CHAT_MSG_MONSTER_WHISPER
Language
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:22
uint32 getMSTime()
Definition Timer.h:12
@ WORLD_SEL_CREATURE_TEXT
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const &message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="", std::string const &addonPrefix="")
Definition Chat.cpp:580
WorldObject const * _target
CreatureTextBuilder(WorldObject *obj, ChatMsg msgtype, uint8 textGroup, uint32 id, Language language, WorldObject const *target)
size_t operator()(WorldPacket *data, LocaleConstant locale) const
LocaleCreatureTextMap mLocaleTextMap
std::string GetLocalizedChatString(uint32 entry, uint8 textGroup, uint32 id, LocaleConstant locale) const
uint32 SendChat(Creature *source, uint8 textGroup, WorldObject const *whisperTarget=NULL, ChatMsg msgType=ChatMsg::CHAT_MSG_ADDON, Language language=Language::LANG_ADDON, CreatureTextRange range=TEXT_RANGE_NORMAL, uint32 sound=0, Team team=TEAM_OTHER, bool gmOnly=false, Player *srcPlr=NULL)
void SetRepeatId(Creature *source, uint8 textGroup, uint8 id)
CreatureTextRepeatMap mTextRepeatMap
void SendEmote(Unit *source, uint32 emote)
bool TextExist(uint32 sourceEntry, uint8 textGroup)
CreatureTextRepeatIds GetRepeatGroup(Creature *source, uint8 textGroup)
void SendNonChatPacket(WorldObject *source, WorldPacket *data, ChatMsg msgType, WorldObject const *whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const
void SendSound(Creature *source, uint32 sound, ChatMsg msgType, WorldObject const *whisperTarget, CreatureTextRange range, Team team, bool gmOnly)
CreatureTextMap mTextMap
float GetRangeForChatType(ChatMsg msgType) const
void SendChatPacket(WorldObject *source, Builder const &builder, ChatMsg msgType, WorldObject const *whisperTarget=NULL, CreatureTextRange range=TEXT_RANGE_NORMAL, Team team=TEAM_OTHER, bool gmOnly=false) const
Definition Field.h:16
uint8 GetUInt8() const
Definition Field.h:26
std::string GetString() const
Definition Field.h:228
float GetFloat() const
Definition Field.h:177
uint32 GetUInt32() const
Definition Field.h:105
MapRefManager PlayerList
Definition Map.h:406
PlayerList const & GetPlayers() const
Definition Map.h:407
iterator end()
iterator begin()
LinkedListHead::Iterator< MapReference const > const_iterator
uint64 GetGUID() const
Definition Object.h:119
Player * ToPlayer()
Definition Object.h:204
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
uint32 GetEntry() const
Definition Object.h:125
static void AddLocaleString(std::string const &s, LocaleConstant locale, StringVector &data)
static void GetLocaleString(const StringVector &data, int loc_idx, std::string &value)
Definition ObjectMgr.h:1353
WorldSession * GetSession() const
Definition Player.h:2417
PlayerTextBuilder(WorldObject *obj, WorldObject *speaker, ChatMsg msgtype, uint8 textGroup, uint32 id, Language language, WorldObject const *target)
WorldObject * _talker
WorldObject * _source
size_t operator()(WorldPacket *data, LocaleConstant locale) const
WorldObject const * _target
Definition Unit.h:1367
void HandleEmoteCommand(uint32 anim_id)
static Player * GetPlayer(WorldObject &object, uint64 guid)
Definition Unit.cpp:4900
virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
Definition Object.cpp:2491
Map * GetMap() const
Definition Object.h:740
std::string const & GetName() const
Definition Object.h:664
uint32 GetAreaId() const
Definition Object.cpp:1602
uint32 GetZoneId() const
Definition Object.cpp:1597
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition Main.cpp:40
@ SMSG_PLAY_SOUND
Definition Opcodes.h:883
#define sWorld
Definition World.h:910
UNORDERED_MAP< uint32, WorldSession * > SessionMap
Definition World.h:543
@ CONFIG_LISTEN_RANGE_YELL
Definition World.h:185
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition World.h:184
@ CONFIG_LISTEN_RANGE_SAY
Definition World.h:183
uint32 duration
uint32 entry
ChatMsg type
std::string text
Language lang
float probability
Emote emote
uint8 id
uint8 group
uint32 sound