OregonCore  revision 3611e8a-git
Your Favourite TBC server
CreatureTextMgr.cpp
Go to the documentation of this file.
1 /*
2 * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "Common.h"
19 #include "DatabaseEnv.h"
20 #include "ObjectMgr.h"
21 #include "Cell.h"
22 #include "CellImpl.h"
23 #include "Chat.h"
24 #include "GridNotifiers.h"
25 #include "GridNotifiersImpl.h"
26 #include "CreatureTextMgr.h"
27 #include "World.h"
28 
30 {
31 public:
32  CreatureTextBuilder(WorldObject* obj, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject* target)
33  : _source(obj), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { }
34 
35  size_t operator()(WorldPacket* data, int loc_idx) const
36  {
37  std::string text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, loc_idx);
38 
40  }
41 
42 private:
50 };
51 
53 {
54 public:
55  PlayerTextBuilder(WorldObject* obj, WorldObject* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject* target)
56  : _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { }
57 
58  size_t operator()(WorldPacket* data, int loc_idx) const
59  {
60  std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, loc_idx);
61 
62  return CreatureTextMgr::BuildMonsterChat(data, _talker, _msgType, text, Language(_language), _target, loc_idx);
63  }
64 
65 private:
74 };
75 
77 {
78  uint32 oldMSTime = getMSTime();
79 
80  mTextMap.clear(); // for reload case
81  //all currently used temp texts are NOT reset
82 
83  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, groupid, id, text, type, language, probability, emote, duration, sound, TextRange FROM creature_text");
84 
85  if (!result)
86  {
87  sLog.outString(">> Loaded 0 ceature texts. DB table `creature_text` is empty.");
88 
89  return;
90  }
91 
92  uint32 textCount = 0;
93 
94  do
95  {
96  Field* fields = result->Fetch();
97  CreatureTextEntry temp;
98 
99  temp.entry = fields[0].GetUInt32();
100  temp.group = fields[1].GetUInt8();
101  temp.id = fields[2].GetUInt8();
102  temp.text = fields[3].GetString();
103  temp.type = ChatMsg(fields[4].GetUInt8());
104  temp.lang = Language(fields[5].GetUInt8());
105  temp.probability = fields[6].GetFloat();
106  temp.emote = Emote(fields[7].GetUInt32());
107  temp.duration = fields[8].GetUInt32();
108  temp.sound = fields[9].GetUInt32();
109  temp.TextRange = CreatureTextRange(fields[10].GetUInt8());
110 
111  if (temp.sound)
112  {
113  if (!sSoundEntriesStore.LookupEntry(temp.sound))
114  {
115  sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Sound %u but sound does not exist.", temp.entry, temp.group, temp.sound);
116  temp.sound = 0;
117  }
118  }
119 
120  if (!GetLanguageDescByID(temp.lang))
121  {
122  sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` using Language %u but Language does not exist.", temp.entry, temp.group, uint32(temp.lang));
123  temp.lang = LANG_UNIVERSAL;
124  }
125 
126  if (temp.type >= MAX_CHAT_MSG_TYPE)
127  {
128  sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Type %u but this Chat Type does not exist.", temp.entry, temp.group, uint32(temp.type));
129  temp.type = CHAT_MSG_SAY;
130  }
131 
132  if (temp.emote)
133  {
134  if (!sEmotesStore.LookupEntry(temp.emote))
135  {
136  sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Emote %u but emote does not exist.", temp.entry, temp.group, uint32(temp.emote));
137  temp.emote = EMOTE_ONESHOT_NONE;
138  }
139  }
140 
141  if (temp.TextRange > TEXT_RANGE_WORLD)
142  {
143  sLog.outError("CreatureTextMgr: Entry %u, Group %u, Id %u in table `creature_text` has incorrect TextRange %u.", temp.entry, temp.group, temp.id, temp.TextRange);
145  }
146 
147  // add the text into our entry's group
148  mTextMap[temp.entry][temp.group].push_back(temp);
149 
150  ++textCount;
151  }
152  while (result->NextRow());
153 
154  sLog.outString(">> Loaded %u creature texts for %lu creatures in %u ms", textCount, mTextMap.size(), GetMSTimeDiffToNow(oldMSTime));
155 }
156 
158 {
159  uint32 oldMSTime = getMSTime();
160 
161  mLocaleTextMap.clear(); // for reload case
162 
163  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, groupid, id, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8 FROM locales_creature_text");
164 
165  if (!result)
166  return;
167 
168  uint32 textCount = 0;
169 
170  do
171  {
172  Field* fields = result->Fetch();
173  CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), uint32(fields[2].GetUInt8()))];
174  for (uint8 i = MAX_LOCALE - 1; i > 0; --i)
175  {
176  LocaleConstant locale = LocaleConstant(i);
177  ObjectMgr::AddLocaleString(fields[3 + i - 1].GetString(), locale, loc.Text);
178  }
179 
180  ++textCount;
181  } while (result->NextRow());
182 
183  sLog.outString(">> Loaded %u creature localized texts in %u ms", textCount, GetMSTimeDiffToNow(oldMSTime));
184 
185 }
186 
187 uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject* whisperTarget /*= nullptr*/, 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 /*= nullptr*/)
188 {
189  if (!source)
190  return 0;
191 
192  CreatureTextMap::const_iterator sList = mTextMap.find(source->GetEntry());
193  if (sList == mTextMap.end())
194  {
195  sLog.outError("CreatureTextMgr: Could not find Text for Creature %s (Entry %u, GUID %u) in 'creature_text' table. Ignoring.", source->GetName(), source->GetEntry(), source->GetGUIDLow());
196  return 0;
197  }
198 
199  CreatureTextHolder const& textHolder = sList->second;
200  CreatureTextHolder::const_iterator itr = textHolder.find(textGroup);
201  if (itr == textHolder.end())
202  {
203  sLog.outError("CreatureTextMgr: Could not find TextGroup %u for Creature %s (Entry %u, GUID %u) in 'creature_text' table. Ignoring.", uint32(textGroup), source->GetName(), source->GetEntry(), source->GetGUIDLow());
204  return 0;
205  }
206 
207  CreatureTextGroup const& textGroupContainer = itr->second; //has all texts in the group
208  CreatureTextRepeatIds repeatGroup = GetRepeatGroup(source, textGroup);//has all textIDs from the group that were already said
209  CreatureTextGroup tempGroup;//will use this to talk after sorting repeatGroup
210 
211  for (CreatureTextGroup::const_iterator giter = textGroupContainer.begin(); giter != textGroupContainer.end(); ++giter)
212  if (std::find(repeatGroup.begin(), repeatGroup.end(), giter->id) == repeatGroup.end())
213  tempGroup.push_back(*giter);
214 
215  if (tempGroup.empty())
216  {
217  source->ClearTextRepeatGroup(textGroup);
218  tempGroup = textGroupContainer;
219  }
220 
221  uint8 count = 0;
222  float lastChance = -1;
223  bool isEqualChanced = true;
224 
225  float totalChance = 0;
226 
227  for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
228  {
229  if (lastChance >= 0 && lastChance != iter->probability)
230  isEqualChanced = false;
231 
232  lastChance = iter->probability;
233  totalChance += iter->probability;
234  ++count;
235  }
236 
237  int32 offset = -1;
238  if (!isEqualChanced)
239  {
240  for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
241  {
242  uint32 chance = uint32(iter->probability);
243  uint32 r = urand(0, 100);
244  ++offset;
245  if (r <= chance)
246  break;
247  }
248  }
249 
250  uint32 pos = 0;
251  if (isEqualChanced || offset < 0)
252  pos = urand(0, count - 1);
253  else if (offset >= 0)
254  pos = offset;
255 
256  CreatureTextGroup::const_iterator iter = tempGroup.begin() + pos;
257 
258  ChatMsg finalType = (msgType == CHAT_MSG_ADDON) ? iter->type : msgType;
259  Language finalLang = (language == LANG_ADDON) ? iter->lang : language;
260  uint32 finalSound = sound ? sound : iter->sound;
261 
262  if (range == TEXT_RANGE_NORMAL)
263  range = iter->TextRange;
264 
265  if (finalSound)
266  SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly);
267 
268  Unit* finalSource = source;
269  if (srcPlr)
270  finalSource = srcPlr;
271 
272  if (iter->emote)
273  SendEmote(finalSource, iter->emote);
274 
275  if (srcPlr)
276  {
277  PlayerTextBuilder builder(source, finalSource, finalSource->getGender(), finalType, iter->group, iter->id, finalLang, whisperTarget);
278  SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
279  }
280  else
281  {
282  CreatureTextBuilder builder(finalSource, finalSource->getGender(), finalType, iter->group, iter->id, finalLang, whisperTarget);
283  SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
284  }
285 
286  if (isEqualChanced || totalChance == 100.0f)
287  SetRepeatId(source, textGroup, iter->id);
288 
289  return iter->duration;
290 }
291 
292 size_t CreatureTextMgr::BuildMonsterChat(WorldPacket* data, WorldObject* source, ChatMsg msgtype, std::string text, Language language, WorldObject* whisperTarget, int loc_idx)
293 {
294  if (!source)
295  return 0;
296 
297  size_t receiverGUIDPos = 0;
299 
300  std::string senderName = "";
301  uint64 senderGuid = 0;
302  if (source)
303  {
304  senderGuid = source->GetGUID();
305  senderName = source->GetNameForLocaleIdx(loc_idx);
306  }
307 
308  std::string receiverName = "";
309  uint64 receiverGuid = 0;
310  if (whisperTarget)
311  {
312  receiverGuid = whisperTarget->GetGUID();
313  receiverName = whisperTarget->GetNameForLocaleIdx(loc_idx);
314  }
315 
316  *data << (uint8)msgtype;
317  *data << (uint32)language;
318  *data << (uint64)senderGuid;
319  *data << (uint32)0; // 2.1.0
320  *data << (uint32)(senderName.length() + 1);
321  *data << senderName.c_str();
322  receiverGUIDPos = data->wpos();
323  *data << (uint64)receiverGuid; // Unit Target
324  if (whisperTarget && !IS_PLAYER_GUID(receiverGuid)) //can only whisper players
325  {
326  *data << uint32(receiverName.length() + 1); // string listener_name_length
327  *data << receiverName.c_str(); // string listener_name
328  }
329  *data << (uint32)(text.length() + 1);
330  *data << text;
331  *data << (uint8)0; // ChatTag
332 
333  return receiverGUIDPos;
334 }
335 
336 void CreatureTextMgr::SendNonChatPacket(WorldPacket* data, WorldObject* source, ChatMsg msgtype, WorldObject* whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const
337 {
338  if (!source)
339  return;
340 
341  switch (msgtype)
342  {
344  {
345  if (!whisperTarget)
346  return;
347 
348  if (Player* whisperPlayer = whisperTarget->ToPlayer())
349  {
350  if (Group* group = whisperPlayer->GetGroup())
351  group->BroadcastPacket(data, false);
352  }
353  return;
354  }
357  {
358  if (range == TEXT_RANGE_NORMAL) // ignores team and gmOnly
359  {
360  if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER)
361  return;
362 
363  whisperTarget->ToPlayer()->GetSession()->SendPacket(data);
364  return;
365  }
366  }
367  break;
368  case CHAT_MSG_SAY://default dist
369  default:
370  break;
371  }
372 
373  switch (range)
374  {
375  case TEXT_RANGE_AREA:
376  {
377  uint32 areaId = source->GetAreaId();
378  Map::PlayerList const& pList = source->GetMap()->GetPlayers();
379  for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
380  if (itr->GetSource()->GetAreaId() == areaId && (!team || (team && itr->GetSource()->GetTeam() == team)) && (!gmOnly || itr->GetSource()->IsGameMaster()))
381  itr->GetSource()->GetSession()->SendPacket(data);
382  }
383  return;
384  case TEXT_RANGE_ZONE:
385  {
386  uint32 zoneId = source->GetZoneId();
387  Map::PlayerList const& pList = source->GetMap()->GetPlayers();
388  for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
389  if (itr->GetSource()->GetZoneId() == zoneId && (!team || (team && itr->GetSource()->GetTeam() == team)) && (!gmOnly || itr->GetSource()->IsGameMaster()))
390  itr->GetSource()->GetSession()->SendPacket(data);
391  }
392  return;
393  case TEXT_RANGE_MAP:
394  {
395  Map::PlayerList const& pList = source->GetMap()->GetPlayers();
396  for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
397  if (!team || ((team && itr->GetSource()->GetTeam() == team) && (!gmOnly || itr->GetSource()->IsGameMaster())))
398  itr->GetSource()->GetSession()->SendPacket(data);
399  }
400  return;
401  case TEXT_RANGE_WORLD:
402  {
403  const SessionMap smap = sWorld.GetAllSessions();
404  for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter)
405  if (Player* plr = (*iter).second->GetPlayer())
406  if (plr->GetSession() && (!team || (team && plr->GetTeam() == team)) && (!gmOnly || plr->IsGameMaster()))
407  plr->GetSession()->SendPacket(data);
408  }
409  return;
410  case TEXT_RANGE_NORMAL:
411  default:
412  break;
413  }
414 
415  float dist = GetRangeForChatType(msgtype);
416  source->SendMessageToSetInRange(data, dist, true);
417 }
418 
420 {
421  float dist = sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY);
422  switch (msgType)
423  {
425  dist = sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL);
426  break;
429  dist = sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE);
430  break;
431  default:
432  break;
433  }
434 
435  return dist;
436 }
437 
438 void CreatureTextMgr::SendSound(Creature* source, uint32 sound, ChatMsg msgType, WorldObject* whisperTarget, CreatureTextRange range, Team team, bool gmOnly)
439 {
440  if (!sound || !source)
441  return;
442 
443  WorldPacket data(SMSG_PLAY_SOUND, 4);
444  data << uint32(sound);
445  SendNonChatPacket(&data, source, msgType, whisperTarget, range, team, gmOnly);
446 }
447 
449 {
450  if (!source)
451  return;
452 
453  source->HandleEmoteCommand(emote);
454 }
455 
456 void CreatureTextMgr::SetRepeatId(Creature* source, uint8 textGroup, uint8 id)
457 {
458  if (!source)
459  return;
460 
461  source->SetTextRepeatId(textGroup, id);
462 }
463 
465 {
466  ASSERT(source);//should never happen
467 
468  return source->GetTextRepeatGroup(textGroup);
469 }
470 
471 bool CreatureTextMgr::TextExist(uint32 sourceEntry, uint8 textGroup)
472 {
473  if (!sourceEntry)
474  return false;
475 
476  CreatureTextMap::const_iterator sList = mTextMap.find(sourceEntry);
477  if (sList == mTextMap.end())
478  {
479  sLog.outDebug("CreatureTextMgr::TextExist: Could not find Text for Creature (entry %u) in 'creature_text' table.", sourceEntry);
480  return false;
481  }
482 
483  CreatureTextHolder const& textHolder = sList->second;
484  CreatureTextHolder::const_iterator itr = textHolder.find(textGroup);
485  if (itr == textHolder.end())
486  {
487  sLog.outDebug("CreatureTextMgr::TextExist: Could not find TextGroup %u for Creature (entry %u).", uint32(textGroup), sourceEntry);
488  return false;
489  }
490 
491  return true;
492 }
493 
494 std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 gender, uint8 textGroup, uint32 id, int loc_idx) const
495 {
496  CreatureTextMap::const_iterator mapitr = mTextMap.find(entry);
497  if (mapitr == mTextMap.end())
498  return "";
499 
500  CreatureTextHolder::const_iterator holderItr = mapitr->second.find(textGroup);
501  if (holderItr == mapitr->second.end())
502  return "";
503 
504  CreatureTextGroup::const_iterator groupItr = holderItr->second.begin();
505  for (; groupItr != holderItr->second.end(); ++groupItr)
506  if (groupItr->id == id)
507  break;
508 
509  if (groupItr == holderItr->second.end())
510  return "";
511 
512  std::string baseText = groupItr->text;
513 
514  LocaleCreatureTextMap::const_iterator locItr = mLocaleTextMap.find(CreatureTextId(entry, uint32(textGroup), id));
515  if (locItr != mLocaleTextMap.end())
516  ObjectMgr::GetLocaleString(locItr->second.Text, loc_idx, baseText);
517 
518  return baseText;
519 }
void SetTextRepeatId(uint8 textGroup, uint8 id)
Definition: Creature.cpp:2642
UNORDERED_MAP< uint32, WorldSession * > SessionMap
Definition: World.h:454
float GetRangeForChatType(ChatMsg msgType) const
void SetRepeatId(Creature *source, uint8 textGroup, uint8 id)
Map * GetMap() const
Definition: Object.h:829
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
static void AddLocaleString(std::string const &s, LocaleConstant locale, StringVector &data)
Definition: ObjectMgr.cpp:7516
Emote
DBCStorage< EmotesEntry > sEmotesStore(EmotesEntryfmt)
std::vector< CreatureTextEntry > CreatureTextGroup
CreatureTextRange TextRange
Definition: Field.h:24
uint32 SendChat(Creature *source, uint8 textGroup, WorldObject *whisperTarget=nullptr, ChatMsg msgType=CHAT_MSG_ADDON, Language language=LANG_ADDON, CreatureTextRange range=TEXT_RANGE_NORMAL, uint32 sound=0, Team team=TEAM_NONE, bool gmOnly=false, Player *srcPlr=nullptr)
uint32 GetZoneId() const
Definition: Object.cpp:1176
WorldObject * _target
std::vector< uint8 > CreatureTextRepeatIds
Definition: Creature.h:456
uint32 getMSTime()
Definition: Timer.h:32
#define sLog
Log class singleton.
Definition: Log.h:187
ChatMsg
ACE_INT32 int32
Definition: Define.h:67
QueryResult_AutoPtr Query(const char *sql)
Definition: Database.cpp:383
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:37
CreatureTextBuilder(WorldObject *obj, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject *target)
static size_t BuildMonsterChat(WorldPacket *data, WorldObject *source, ChatMsg msgtype, std::string text, Language language, WorldObject *whisperTarget, int loc_idx)
uint32 GetGUIDLow() const
Definition: Object.h:160
PlayerTextBuilder(WorldObject *obj, WorldObject *speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject *target)
iterator begin()
Definition: MapRefManager.h:48
void SendPacket(WorldPacket const *packet)
UNORDERED_MAP< uint8, CreatureTextGroup > CreatureTextHolder
const char * GetString() const
Definition: Field.h:41
Player * ToPlayer()
Definition: Object.h:386
#define IS_PLAYER_GUID(Guid)
Definition: ObjectGuid.h:69
size_t wpos() const
Definition: ByteBuffer.h:264
uint8 GetTypeId() const
Definition: Object.h:204
bool TextExist(uint32 sourceEntry, uint8 textGroup)
Team
ACE_UINT8 uint8
Definition: Define.h:73
Language
const uint8 MAX_LOCALE
Definition: Common.h:224
WorldObject * _talker
#define sCreatureTextMgr
size_t operator()(WorldPacket *data, int loc_idx) const
CreatureTextRepeatIds GetRepeatGroup(Creature *source, uint8 textGroup)
uint32 GetAreaId() const
Definition: Object.cpp:1181
void SendNonChatPacket(WorldPacket *data, WorldObject *source, ChatMsg msgtype, WorldObject *whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const
std::string GetLocalizedChatString(uint32 entry, uint8 gender, uint8 textGroup, uint32 id, int loc_idx) const
CreatureTextRange
WorldObject * _source
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
const char * GetName() const
Definition: Object.h:692
size_t operator()(WorldPacket *data, int loc_idx) const
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition: ObjectMgr.cpp:269
ACE_UINT64 uint64
Definition: Define.h:70
PlayerList const & GetPlayers() const
Definition: Map.h:491
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:94
static void GetLocaleString(const StringVector &data, int loc_idx, std::string &value)
Definition: ObjectMgr.h:1151
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
uint8 getGender() const
Definition: Unit.h:1041
virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
Definition: Object.cpp:1930
#define ASSERT
Definition: Errors.h:33
void HandleEmoteCommand(uint32 anim_id)
Definition: Unit.cpp:1921
uint32 GetEntry() const
Definition: Object.h:186
WorldSession * GetSession() const
Definition: Player.h:1959
LocaleConstant
Definition: Common.h:211
#define sWorld
Definition: World.h:860
CreatureTextRepeatIds GetTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:2651
void LoadCreatureTextLocales()
void SendEmote(Unit *source, uint32 emote)
ACE_UINT32 uint32
Definition: Define.h:71
virtual const char * GetNameForLocaleIdx(int32) const
Definition: Object.h:701
Definition: Unit.h:884
static Player * GetPlayer(WorldObject &object, uint64 guid)
Definition: Unit.cpp:10597
Definition: Player.h:922
void SendSound(Creature *source, uint32 sound, ChatMsg msgType, WorldObject *whisperTarget, CreatureTextRange range, Team team, bool gmOnly)
#define MAX_CHAT_MSG_TYPE
void ClearTextRepeatGroup(uint8 textGroup)
Definition: Creature.cpp:2662
iterator end()
Definition: MapRefManager.h:52
Definition: Group.h:154
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:71
const uint64 & GetGUID() const
Definition: Object.h:156