OregonCore  revision be9e804-git
Your Favourite TBC server
Object.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 <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "SharedDefines.h"
20 #include "WorldPacket.h"
21 #include "Opcodes.h"
22 #include "World.h"
23 #include "Object.h"
24 #include "Creature.h"
25 #include "Player.h"
26 #include "ObjectMgr.h"
27 #include "WorldSession.h"
28 #include "UpdateData.h"
29 #include "UpdateMask.h"
30 #include "Utilities/Util.h"
31 #include "ObjectAccessor.h"
32 #include "Transports.h"
33 #include "VMapFactory.h"
34 #include "CellImpl.h"
35 #include "GridNotifiers.h"
36 #include "GridNotifiersImpl.h"
37 #include "TemporarySummon.h"
38 #include "Totem.h"
39 #include "OutdoorPvPMgr.h"
40 #include "packet_builder.h"
41 #include "MapManager.h"
42 
44 {
45  switch (guid_hi)
46  {
47  case HIGHGUID_ITEM:
48  return TYPEID_ITEM;
49  //case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER == HIGHGUID_ITEM currently
50  case HIGHGUID_UNIT:
51  return TYPEID_UNIT;
52  case HIGHGUID_PET:
53  return TYPEID_UNIT;
54  case HIGHGUID_PLAYER:
55  return TYPEID_PLAYER;
57  return TYPEID_GAMEOBJECT;
59  return TYPEID_DYNAMICOBJECT;
60  case HIGHGUID_CORPSE:
61  return TYPEID_CORPSE;
63  return TYPEID_GAMEOBJECT;
64  }
65  return TYPEID_OBJECT; // unknown
66 }
67 
69 {
72 
73  m_uint32Values = 0;
75  m_valuesCount = 0;
76 
77  m_inWorld = false;
78  m_objectUpdated = false;
79 }
80 
82 {
83  // this may happen because there are many !create/delete
84  if (IsWorldObject() && m_currMap)
85  {
86  if (GetTypeId() == TYPEID_CORPSE)
87  {
88  sLog.outError("Crash alert! Object::~Object Corpse guid=" UI64FMTD ", type=%d, entry=%u deleted but still in map!!", GetGUID(), ((Corpse*)this)->GetType(), GetEntry());
89  ASSERT(false);
90  }
91  ResetMap();
92  }
93 }
94 
96 {
97  if (IsInWorld())
98  {
99  // Do NOT call RemoveFromWorld here, if the object is a player it will crash
100  sLog.outError("Crash alert! Object::~Object (GUID: %u TypeId: %u) deleted but still in world!!", GetGUIDLow(), GetTypeId());
101  ASSERT(false);
102  }
103 
104  if (m_objectUpdated)
105  {
106  sLog.outError("Crash alert! Object::~Object (GUID: %u TypeId: %u) deleted but still has updated status!!", GetGUIDLow(), GetTypeId());
107  ASSERT(false);
108  }
109 
110  delete [] m_uint32Values;
111  delete [] m_uint32Values_mirror;
112 }
113 
115 {
117  memset(m_uint32Values, 0, m_valuesCount * sizeof(uint32));
118 
120  memset(m_uint32Values_mirror, 0, m_valuesCount * sizeof(uint32));
121 
122  m_objectUpdated = false;
123 }
124 
125 void Object::_Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
126 {
127  if (!m_uint32Values)
128  _InitValues();
129 
130  uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh);
133  m_PackGUID.Set(guid);
134 }
135 
137 {
138  ByteBuffer buf(500);
139 
140  buf << uint8(UPDATETYPE_MOVEMENT);
141  buf << GetGUID();
142 
143  _BuildMovementUpdate(&buf, flags);
144 
145  data->AddUpdateBlock(buf);
146 }
147 
149 {
150  if (!target)
151  return;
152 
153  uint8 updatetype = UPDATETYPE_CREATE_OBJECT;
154  uint8 flags = m_updateFlag;
155 
157  if (target == this) // building packet for oneself
158  flags |= UPDATEFLAG_SELF;
159 
160  if (flags & UPDATEFLAG_HAS_POSITION)
161  {
162  // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
164  updatetype = UPDATETYPE_CREATE_OBJECT2;
165 
166  // UPDATETYPE_CREATE_OBJECT2 for pets...
167  if (target->GetPetGUID() == GetGUID())
168  updatetype = UPDATETYPE_CREATE_OBJECT2;
169 
170  // UPDATETYPE_CREATE_OBJECT2 for some gameobject types...
172  {
173  switch (((GameObject*)this)->GetGoType())
174  {
179  updatetype = UPDATETYPE_CREATE_OBJECT2;
180  break;
182  flags |= UPDATEFLAG_TRANSPORT;
183  break;
184  default:
185  break;
186  }
187  }
188  }
189 
190  //sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2);
191 
192  ByteBuffer buf(500);
193  buf << (uint8)updatetype;
194  //buf << GetPackGUID(); //client crashes when using this
195  buf << (uint8)0xFF << GetGUID();
196  buf << (uint8)m_objectTypeId;
197 
198  _BuildMovementUpdate(&buf, flags);
199 
200  UpdateMask updateMask;
201  updateMask.SetCount(m_valuesCount);
202  _SetCreateBits(&updateMask, target);
203  _BuildValuesUpdate(updatetype, &buf, &updateMask, target);
204  data->AddUpdateBlock(buf);
205 }
206 
208 {
209  // send create update to player
210  UpdateData upd;
211  WorldPacket packet;
212 
213  BuildCreateUpdateBlockForPlayer(&upd, player);
214  upd.BuildPacket(&packet);
215  player->GetSession()->SendPacket(&packet);
216 }
217 
219 {
220  ByteBuffer buf(500);
221 
222  buf << (uint8) UPDATETYPE_VALUES;
223  //buf << GetPackGUID(); //client crashes when using this. but not have crash in debug mode
224  buf << (uint8)0xFF;
225  buf << GetGUID();
226 
227  UpdateMask updateMask;
228  updateMask.SetCount(m_valuesCount);
229 
230  _SetUpdateBits(&updateMask, target);
231  _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
232 
233  data->AddUpdateBlock(buf);
234 }
235 
237 {
238  data->AddOutOfRangeGUID(GetGUID());
239 }
240 
241 void Object::DestroyForPlayer(Player* target, bool onDeath) const
242 {
243  ASSERT(target);
244 
245  WorldPacket data(SMSG_DESTROY_OBJECT, 8 + 1);
246  data << uint64(GetGUID());
249  data << uint8(onDeath ? 1 : 0);
250  target->GetSession()->SendPacket(&data);
251 }
252 
253 void Object::_BuildMovementUpdate(ByteBuffer* data, uint8 updateFlags) const
254 {
255  uint32 moveFlags = MOVEMENTFLAG_NONE;
256 
257  *data << uint8(updateFlags); // update flags
258 
259  if (updateFlags & UPDATEFLAG_LIVING)
260  {
261  switch (GetTypeId())
262  {
263  case TYPEID_UNIT:
264  {
265  moveFlags = ((Unit*)this)->GetUnitMovementFlags();
266  moveFlags &= ~MOVEMENTFLAG_ONTRANSPORT;
267  }
268  break;
269  case TYPEID_PLAYER:
270  {
271  moveFlags = ToPlayer()->GetUnitMovementFlags();
272 
273  if (ToPlayer()->GetTransport())
274  moveFlags |= MOVEMENTFLAG_ONTRANSPORT;
275  else
276  moveFlags &= ~MOVEMENTFLAG_ONTRANSPORT;
277 
278  }
279  break;
280  }
281 
282  *data << uint32(moveFlags); // movement flags
283  *data << uint8(0); // movemoveFlags
284  *data << uint32(getMSTime()); // time (in milliseconds)
285  }
286 
287  // 0x40
288  if (updateFlags & UPDATEFLAG_HAS_POSITION)
289  {
290  // 0x02
291  if (updateFlags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
292  {
293  *data << float(0);
294  *data << float(0);
295  *data << float(0);
296  *data << float(((WorldObject*)this)->GetOrientation());
297  }
298  else
299  {
300  *data << float(((WorldObject*)this)->GetPositionX());
301  *data << float(((WorldObject*)this)->GetPositionY());
302  *data << float(((WorldObject*)this)->GetPositionZ());
303  *data << float(((WorldObject*)this)->GetOrientation());
304  }
305  }
306 
307  // 0x20
308  if (updateFlags & UPDATEFLAG_LIVING)
309  {
310  // 0x00000200
311  if (moveFlags & MOVEMENTFLAG_ONTRANSPORT)
312  {
313  if (GetTypeId() == TYPEID_PLAYER)
314  {
315  *data << (uint64)ToPlayer()->GetTransport()->GetGUID();
316  *data << (float)ToPlayer()->GetTransOffsetX();
317  *data << (float)ToPlayer()->GetTransOffsetY();
318  *data << (float)ToPlayer()->GetTransOffsetZ();
319  *data << (float)ToPlayer()->GetTransOffsetO();
320  *data << (uint32)ToPlayer()->GetTransTime();
321  }
322  //Oregon currently not have support for other than player on transport
323  }
324 
325  // 0x02200000
326  if (moveFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))
327  {
328  if (GetTypeId() == TYPEID_PLAYER)
329  *data << (float)ToPlayer()->m_movementInfo.s_pitch;
330  else
331  *data << float(0); // is't part of movement packet, we must store and send it...
332  }
333 
334  if (GetTypeId() == TYPEID_PLAYER)
335  *data << (uint32)ToPlayer()->m_movementInfo.GetFallTime();
336  else
337  *data << uint32(0); // last fall time
338 
339  // 0x00001000
340  if (moveFlags & MOVEMENTFLAG_FALLING)
341  {
342  if (GetTypeId() == TYPEID_PLAYER)
343  {
344  *data << float(ToPlayer()->m_movementInfo.j_velocity);
345  *data << float(ToPlayer()->m_movementInfo.j_sinAngle);
346  *data << float(ToPlayer()->m_movementInfo.j_cosAngle);
347  *data << float(ToPlayer()->m_movementInfo.j_xyspeed);
348  }
349  else
350  {
351  *data << float(0);
352  *data << float(0);
353  *data << float(0);
354  *data << float(0);
355  }
356  }
357 
358  // 0x04000000
359  if (moveFlags & MOVEMENTFLAG_SPLINE_ELEVATION)
360  {
361  if (GetTypeId() == TYPEID_PLAYER)
362  *data << float(ToPlayer()->m_movementInfo.u_unk1);
363  else
364  *data << float(0);
365  }
366 
367  // Unit speeds
368  *data << ((Unit*)this)->GetSpeed(MOVE_WALK);
369  *data << ((Unit*)this)->GetSpeed(MOVE_RUN);
370  *data << ((Unit*)this)->GetSpeed(MOVE_RUN_BACK);
371  *data << ((Unit*)this)->GetSpeed(MOVE_SWIM);
372  *data << ((Unit*)this)->GetSpeed(MOVE_SWIM_BACK);
373  *data << ((Unit*)this)->GetSpeed(MOVE_FLIGHT);
374  *data << ((Unit*)this)->GetSpeed(MOVE_FLIGHT_BACK);
375  *data << ((Unit*)this)->GetSpeed(MOVE_TURN_RATE);
376 
377  // 0x08000000
378  if (moveFlags & MOVEMENTFLAG_SPLINE_ENABLED)
379  Movement::PacketBuilder::WriteCreate(*((Unit*)this)->movespline, *data);
380  }
381 
382  // 0x8
383  if (updateFlags & UPDATEFLAG_LOWGUID)
384  {
385  switch (GetTypeId())
386  {
387  case TYPEID_OBJECT:
388  case TYPEID_ITEM:
389  case TYPEID_CONTAINER:
390  case TYPEID_GAMEOBJECT:
392  case TYPEID_CORPSE:
393  *data << uint32(GetGUIDLow()); // GetGUIDLow()
394  break;
395  case TYPEID_UNIT:
396  *data << uint32(0x0000000B); // unk, can be 0xB or 0xC
397  break;
398  case TYPEID_PLAYER:
399  if (updateFlags & UPDATEFLAG_SELF)
400  *data << uint32(0x00000015); // unk, can be 0x15 or 0x22
401  else
402  *data << uint32(0x00000008); // unk, can be 0x7 or 0x8
403  break;
404  default:
405  *data << uint32(0x00000000); // unk
406  break;
407  }
408  }
409 
410  // 0x10
411  if (updateFlags & UPDATEFLAG_HIGHGUID)
412  {
413  switch (GetTypeId())
414  {
415  case TYPEID_OBJECT:
416  case TYPEID_ITEM:
417  case TYPEID_CONTAINER:
418  case TYPEID_GAMEOBJECT:
420  case TYPEID_CORPSE:
421  *data << uint32(GetGUIDHigh()); // GetGUIDHigh()
422  break;
423  default:
424  *data << uint32(0x00000000); // unk
425  break;
426  }
427  }
428 
429  // 0x4
430  if (updateFlags & UPDATEFLAG_HAS_ATTACKING_TARGET) // packed guid (probably target guid)
431  {
432  if (Unit const* me = ToUnit())
433  {
434  if (me->GetVictim())
435  *data << me->GetVictim()->GetPackGUID();
436  else
437  *data << uint8(0);
438  }
439  else
440  *data << uint8(0);
441  }
442 
443  // 0x2
444  if (updateFlags & UPDATEFLAG_TRANSPORT)
445  {
446  *data << uint32(getMSTime()); // ms time
447  }
448 }
449 
450 void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, UpdateMask* updateMask, Player* target) const
451 {
452  if (!target)
453  return;
454 
455  bool IsActivateToQuest = false;
456  if (updatetype == UPDATETYPE_CREATE_OBJECT || updatetype == UPDATETYPE_CREATE_OBJECT2)
457  {
458  if (isType(TYPEMASK_GAMEOBJECT) && !((GameObject*)this)->IsTransport())
459  {
460  if (((GameObject*)this)->ActivateToQuest(target) || target->IsGameMaster())
461  IsActivateToQuest = true;
462 
463  updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
464 
466  updateMask->SetBit(GAMEOBJECT_ARTKIT);
467  }
468  }
469  else //case UPDATETYPE_VALUES
470  {
471  if (isType(TYPEMASK_GAMEOBJECT) && !((GameObject*)this)->IsTransport())
472  {
473  if (((GameObject*)this)->ActivateToQuest(target) || target->IsGameMaster())
474  IsActivateToQuest = true;
475 
476  updateMask->SetBit(GAMEOBJECT_DYN_FLAGS);
477  updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS);
478  }
479  }
480 
481  ASSERT(updateMask && updateMask->GetCount() == m_valuesCount);
482 
483  *data << (uint8)updateMask->GetBlockCount();
484  data->append(updateMask->GetMask(), updateMask->GetLength());
485 
486  // 2 specialized loops for speed optimization in non-unit case
487  if (isType(TYPEMASK_UNIT)) // unit (creature/player) case
488  {
489  for (uint16 index = 0; index < m_valuesCount; index ++)
490  {
491  if (updateMask->GetBit(index))
492  {
493  // remove custom flag before send
494  if (index == UNIT_NPC_FLAGS)
495  *data << uint32(m_uint32Values[index]);
496  // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
497  else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
498  {
499  // convert from float to uint32 and send
500  *data << uint32(m_floatValues[ index ] < 0 ? 0 : m_floatValues[ index ]);
501  }
502  // there are some float values which may be negative or can't get negative due to other checks
503  else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
506  (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
507  *data << uint32(m_floatValues[ index ]);
508  // Gamemasters should be always able to select units - remove not selectable flag
509  else if (index == UNIT_FIELD_FLAGS && target->IsGameMaster())
510  *data << (m_uint32Values[ index ] & ~UNIT_FLAG_NOT_SELECTABLE);
511  // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
512  else if (index == UNIT_FIELD_DISPLAYID && GetTypeId() == TYPEID_UNIT)
513  {
514  const CreatureInfo* cinfo = ToCreature()->GetCreatureTemplate();
516  {
517  if (target->IsGameMaster())
518  {
519  if (cinfo->modelid1)
520  *data << cinfo->modelid1;
521  else
522  *data << 17519; // world invisible trigger's model
523  }
524  else
525  {
526  *data << 11686; // world invisible trigger's model
527  }
528  }
529  else
530  *data << m_uint32Values[ index ];
531  }
532  // hide lootable animation for unallowed players
533  else if (index == UNIT_DYNAMIC_FLAGS && GetTypeId() == TYPEID_UNIT)
534  {
535  uint32 value = m_uint32Values[index];
536 
537  if (Creature* creature = (Creature*)this)
538  if (!creature->loot.isLooted())
539  if (!(value & UNIT_DYNFLAG_LOOTABLE))
540  {
541  creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
542  value = value | UNIT_DYNFLAG_LOOTABLE;
543  }
544 
545  if (!target->isAllowedToLoot((Creature*)this))
546  if (value & UNIT_DYNFLAG_LOOTABLE)
547  value = value & ~UNIT_DYNFLAG_LOOTABLE;
548 
549  bool tapped = ToCreature()->isTappedBy(target->ToPlayer());
550 
551  if (value & UNIT_DYNFLAG_OTHER_TAGGER && tapped)
552  value = value & ~UNIT_DYNFLAG_OTHER_TAGGER;
553 
554  *data << value;
555  }
556 
557  // hide RAF menu to non-RAF linked friends
558  else if (index == UNIT_DYNAMIC_FLAGS && GetTypeId() == TYPEID_PLAYER)
559  {
560  if (sObjectMgr.GetRAFLinkStatus(target->ToPlayer(), this->ToPlayer()) != RAF_LINK_NONE)
561  *data << (m_uint32Values[ index ]);
562  else
563  *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_REFER_A_FRIEND);
564  }
565  // FG: pretend that OTHER players in own group are friendly ("blue")
566  else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
567  {
568  bool ch = false;
569  if (target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER && target != this)
570  {
571  if (target->IsInSameGroupWith(ToPlayer()) || target->IsInSameRaidWith(ToPlayer()))
572  {
573  if (index == UNIT_FIELD_BYTES_2)
574  {
575  DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (flag)", target->GetName(), ToPlayer()->GetName());
576  *data << (m_uint32Values[ index ] & ((UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5) << 8)); // this flag is at uint8 offset 1 !!
577 
578  ch = true;
579  }
580  else if (index == UNIT_FIELD_FACTIONTEMPLATE)
581  {
582  FactionTemplateEntry const* ft1, *ft2;
584  ft2 = target->ToPlayer()->GetFactionTemplateEntry();
585  if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
586  {
587  uint32 faction = target->ToPlayer()->GetFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
588  DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (faction %u)", target->GetName(), ToPlayer()->GetName(), faction);
589  *data << uint32(faction);
590  ch = true;
591  }
592  }
593  }
594  }
595  if (!ch)
596  *data << m_uint32Values[ index ];
597  }
598  else if (index == UNIT_FIELD_HEALTH)
599  {
600  if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER)
601  {
602  const Unit* me = reinterpret_cast<const Unit*>(this);
603  if (me->ShouldRevealHealthTo(target))
604  *data << m_uint32Values[ index ];
605  else
606  *data << uint32(std::ceil(me->GetHealthPct()));
607  }
608  else
609  *data << m_uint32Values[ index ];
610  }
611  else if (index == UNIT_FIELD_MAXHEALTH)
612  {
613  if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER)
614  {
615  const Unit* me = reinterpret_cast<const Unit*>(this);
616  if (me->ShouldRevealHealthTo(target))
617  *data << m_uint32Values[ index ];
618  else
619  *data << uint32(100);
620  }
621  else
622  *data << m_uint32Values[ index ];
623  }
624  else
625  {
626  // send in current format (float as float, uint32 as uint32)
627  *data << m_uint32Values[ index ];
628  }
629  }
630  }
631  }
632  else if (isType(TYPEMASK_GAMEOBJECT)) // gameobject case
633  {
634  for (uint16 index = 0; index < m_valuesCount; ++index)
635  {
636  if (updateMask->GetBit(index))
637  {
638  // send in current format (float as float, uint32 as uint32)
639  if (index == GAMEOBJECT_DYN_FLAGS)
640  {
641  if (IsActivateToQuest)
642  {
643  switch (((GameObject*)this)->GetGoType())
644  {
648  *data << uint16(-1);
649  break;
650  default:
651  *data << uint32(0); // unknown, not happen.
652  break;
653  }
654  }
655  else
656  *data << uint32(0); // disable quest object
657  }
658  else
659  *data << m_uint32Values[ index ]; // other cases
660  }
661  }
662  }
663  else // other objects case (no special index checks)
664  {
665  for (uint16 index = 0; index < m_valuesCount; ++index)
666  {
667  if (updateMask->GetBit(index))
668  {
669  // send in current format (float as float, uint32 as uint32)
670  *data << m_uint32Values[ index ];
671  }
672  }
673  }
674 }
675 
676 void Object::ClearUpdateMask(bool remove)
677 {
679 
680  if (m_objectUpdated)
681  {
682  if (remove)
684  m_objectUpdated = false;
685  }
686 }
687 
689 {
690  UpdateDataMapType::iterator iter = data_map.find(pl);
691 
692  if (iter == data_map.end())
693  {
694  std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(pl, UpdateData()));
695  ASSERT(p.second);
696  iter = p.first;
697  }
698 
699  BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
700 }
701 
702 bool Object::LoadValues(const char* data)
703 {
704  if (!m_uint32Values) _InitValues();
705 
706  Tokens tokens = StrSplit(data, " ");
707 
708  if (tokens.size() != m_valuesCount)
709  return false;
710 
711  Tokens::iterator iter;
712  int index;
713  for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, ++index)
714  m_uint32Values[index] = atol((*iter).c_str());
715 
716  return true;
717 }
718 
719 void Object::_LoadIntoDataField(const char* data, uint32 startOffset, uint32 count)
720 {
721  if (!data)
722  return;
723 
724  Tokens tokens = StrSplit(data, " ");
725 
726  if (tokens.size() != count)
727  return;
728 
729  Tokens::iterator iter;
730  uint32 index;
731  for (iter = tokens.begin(), index = 0; index < count; ++iter, ++index)
732  m_uint32Values[startOffset + index] = atol((*iter).c_str());
733 }
734 
735 void Object::_SetUpdateBits(UpdateMask* updateMask, Player* /*target*/) const
736 {
738  uint32* mirror = m_uint32Values_mirror;
739 
740  for (uint16 index = 0; index < m_valuesCount; ++index, ++value, ++mirror)
741  {
742  if (*mirror != *value)
743  updateMask->SetBit(index);
744  }
745 }
746 
747 void Object::_SetCreateBits(UpdateMask* updateMask, Player* /*target*/) const
748 {
750 
751  for (uint16 index = 0; index < m_valuesCount; ++index, ++value)
752  {
753  if (*value)
754  updateMask->SetBit(index);
755  }
756 }
757 
759 {
760  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
761 
762  if (m_int32Values[ index ] != value)
763  {
764  m_int32Values[ index ] = value;
765 
766  if (m_inWorld)
767  {
768  if (!m_objectUpdated)
769  {
771  m_objectUpdated = true;
772  }
773  }
774  }
775 }
776 
778 {
779  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
780 
781  if (m_uint32Values[ index ] != value)
782  {
783  m_uint32Values[ index ] = value;
784 
785  if (m_inWorld)
786  {
787  if (!m_objectUpdated)
788  {
790  m_objectUpdated = true;
791  }
792  }
793  }
794 }
795 
797 {
798  ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
799  if (*((uint64*) & (m_uint32Values[ index ])) != value)
800  {
801  m_uint32Values[ index ] = *((uint32*)&value);
802  m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1);
803 
804  if (m_inWorld)
805  {
806  if (!m_objectUpdated)
807  {
809  m_objectUpdated = true;
810  }
811  }
812  }
813 }
814 
816 {
817  ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true));
818  if (value && !*((uint64*) & (m_uint32Values[index])))
819  {
820  m_uint32Values[ index ] = *((uint32*)&value);
821  m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1);
822 
823  if (m_inWorld)
824  {
825  if (!m_objectUpdated)
826  {
828  m_objectUpdated = true;
829  }
830  }
831  return true;
832  }
833  return false;
834 }
835 
837 {
838  ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true));
839  if (value && *((uint64*) & (m_uint32Values[index])) == value)
840  {
841  m_uint32Values[ index ] = 0;
842  m_uint32Values[ index + 1 ] = 0;
843 
844  if (m_inWorld)
845  {
846  if (!m_objectUpdated)
847  {
849  m_objectUpdated = true;
850  }
851  }
852  return true;
853  }
854  return false;
855 }
856 
858 {
859  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
860 
861  if (m_floatValues[ index ] != value)
862  {
863  m_floatValues[ index ] = value;
864 
865  if (m_inWorld)
866  {
867  if (!m_objectUpdated)
868  {
870  m_objectUpdated = true;
871  }
872  }
873  }
874 }
875 
877 {
878  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
879 
880  if (offset > 4)
881  {
882  sLog.outError("Object::SetByteValue: wrong offset %u", offset);
883  return;
884  }
885 
886  if (uint8(m_uint32Values[ index ] >> (offset * 8)) != value)
887  {
888  m_uint32Values[ index ] &= ~uint32(uint32(0xFF) << (offset * 8));
889  m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 8));
890 
891  if (m_inWorld)
892  {
893  if (!m_objectUpdated)
894  {
896  m_objectUpdated = true;
897  }
898  }
899  }
900 }
901 
903 {
904  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
905 
906  if (offset > 2)
907  {
908  sLog.outError("Object::SetUInt16Value: wrong offset %u", offset);
909  return;
910  }
911 
912  if (uint16(m_uint32Values[ index ] >> (offset * 16)) != value)
913  {
914  m_uint32Values[ index ] &= ~uint32(uint32(0xFFFF) << (offset * 16));
915  m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 16));
916 
917  if (m_inWorld)
918  {
919  if (!m_objectUpdated)
920  {
922  m_objectUpdated = true;
923  }
924  }
925  }
926 }
927 
929 {
930  if (value < 0)
931  value = 0.0f;
932 
933  SetFloatValue(index, value);
934 }
935 
937 {
938  if (value < 0)
939  value = 0;
940 
941  SetUInt32Value(index, uint32(value));
942 }
943 
945 {
946  int32 cur = GetUInt32Value(index);
947  cur += (apply ? val : -val);
948  if (cur < 0)
949  cur = 0;
950  SetUInt32Value(index, cur);
951 }
952 
954 {
955  int32 cur = GetInt32Value(index);
956  cur += (apply ? val : -val);
957  SetInt32Value(index, cur);
958 }
959 
960 void Object::ApplyModSignedFloatValue(uint16 index, float val, bool apply)
961 {
962  float cur = GetFloatValue(index);
963  cur += (apply ? val : -val);
964  SetFloatValue(index, cur);
965 }
966 
967 void Object::ApplyPercentModFloatValue(uint16 index, float val, bool apply)
968 {
969  float value = GetFloatValue(index);
970  ApplyPercentModFloatVar(value, val, apply);
971  SetFloatValue(index, value);
972 }
973 
974 void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
975 {
976  float cur = GetFloatValue(index);
977  cur += (apply ? val : -val);
978  if (cur < 0)
979  cur = 0;
980  SetFloatValue(index, cur);
981 }
982 
983 void Object::SetFlag(uint16 index, uint32 newFlag)
984 {
985  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
986  uint32 oldval = m_uint32Values[ index ];
987  uint32 newval = oldval | newFlag;
988 
989  if (oldval != newval)
990  {
991  m_uint32Values[ index ] = newval;
992 
993  if (m_inWorld)
994  {
995  if (!m_objectUpdated)
996  {
998  m_objectUpdated = true;
999  }
1000  }
1001  }
1002 }
1003 
1004 void Object::RemoveFlag(uint16 index, uint32 oldFlag)
1005 {
1006  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1008 
1009  uint32 oldval = m_uint32Values[ index ];
1010  uint32 newval = oldval & ~oldFlag;
1011 
1012  if (oldval != newval)
1013  {
1014  m_uint32Values[ index ] = newval;
1015 
1016  if (m_inWorld)
1017  {
1018  if (!m_objectUpdated)
1019  {
1021  m_objectUpdated = true;
1022  }
1023  }
1024  }
1025 }
1026 
1027 void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
1028 {
1029  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1030 
1031  if (offset > 4)
1032  {
1033  sLog.outError("Object::SetByteFlag: wrong offset %u", offset);
1034  return;
1035  }
1036 
1037  if (!(uint8(m_uint32Values[ index ] >> (offset * 8)) & newFlag))
1038  {
1039  m_uint32Values[ index ] |= uint32(uint32(newFlag) << (offset * 8));
1040 
1041  if (m_inWorld)
1042  {
1043  if (!m_objectUpdated)
1044  {
1046  m_objectUpdated = true;
1047  }
1048  }
1049  }
1050 }
1051 
1052 void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag)
1053 {
1054  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1055 
1056  if (offset > 4)
1057  {
1058  sLog.outError("Object::RemoveByteFlag: wrong offset %u", offset);
1059  return;
1060  }
1061 
1062  if (uint8(m_uint32Values[ index ] >> (offset * 8)) & oldFlag)
1063  {
1064  m_uint32Values[ index ] &= ~uint32(uint32(oldFlag) << (offset * 8));
1065 
1066  if (m_inWorld)
1067  {
1068  if (!m_objectUpdated)
1069  {
1071  m_objectUpdated = true;
1072  }
1073  }
1074  }
1075 }
1076 
1077 bool Object::PrintIndexError(uint32 index, bool set) const
1078 {
1079  sLog.outError("Attempt %s invalid value field: %u (count: %u) for object typeid: %u type mask: %u", (set ? "set value to" : "get value from"), index, m_valuesCount, GetTypeId(), m_objectType);
1080 
1081  // assert must fail after function call
1082  return false;
1083 }
1084 
1085 WorldObject::WorldObject(bool isWorldObject):
1086  WorldLocation()
1087  , m_groupLootTimer(0)
1088  , lootingGroupLeaderGUID(0)
1089  , m_isWorldObject(isWorldObject)
1090  , m_name("")
1091  , m_isActive(false)
1092  , m_visibilityDistanceOverride(0)
1093  , m_zoneScript(NULL)
1094  , m_currMap(NULL)
1095  , m_InstanceId(0)
1096  , m_phaseMask(PHASEMASK_NORMAL)
1097  , m_notifyflags(0), m_executed_notifies(0)
1098 {
1101 }
1102 
1104 {
1105  if (!IsInWorld())
1106  return;
1107 
1108  GetMap()->AddObjectToSwitchList(this, on);
1109 }
1110 
1112 {
1113  if (m_isWorldObject)
1114  return true;
1115 
1116  if (ToCreature() && ToCreature()->m_isTempWorldObject)
1117  return true;
1118 
1119  return false;
1120 }
1121 
1123 {
1124  if (m_isActive == on)
1125  return;
1126 
1127  if (GetTypeId() == TYPEID_PLAYER)
1128  return;
1129 
1130  m_isActive = on;
1131 
1132  if (on && !IsInWorld())
1133  return;
1134 
1135  Map* map = FindMap();
1136  if (!map)
1137  return;
1138 
1139  if (on)
1140  {
1141  if (GetTypeId() == TYPEID_UNIT)
1142  map->AddToActive(ToCreature());
1143  else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
1144  map->AddToActive((DynamicObject*)this);
1145  }
1146  else
1147  {
1148  if (GetTypeId() == TYPEID_UNIT)
1149  map->RemoveFromActive(ToCreature());
1150  else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
1151  map->RemoveFromActive((DynamicObject*)this);
1152  }
1153 }
1154 
1156 {
1157  if (GetTypeId() == TYPEID_PLAYER)
1158  return;
1159 
1160  switch (type)
1161  {
1162  case VISDIST_TINY:
1164  break;
1165  case VISDIST_SMALL:
1167  break;
1168  case VISDIST_LARGE:
1170  break;
1171  case VISDIST_GIGANTIC:
1173  break;
1174  default:
1176  }
1177 }
1178 
1180 {
1181  if (IsInWorld())
1182  RemoveFromWorld();
1183 }
1184 
1185 void WorldObject::_Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask)
1186 {
1187  Object::_Create(guidlow, 0, guidhigh);
1188 
1189  m_phaseMask = phaseMask;
1190 }
1191 
1193 {
1194  if (!IsInWorld())
1195  return;
1196 
1198 
1200 }
1201 
1203 {
1205 }
1206 
1208 {
1210 }
1211 
1213 {
1214  Map* map = GetMap();
1215  return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;
1216 }
1217 
1219 {
1220  float dz = fabs(GetPositionZ() - obj->GetPositionZ());
1221  float sizefactor = GetObjectSize() + obj->GetObjectSize();
1222  float dist = dz - sizefactor;
1223  return (dist > 0 ? dist : 0);
1224 }
1225 
1226 float WorldObject::GetDistanceSqr(float x, float y, float z) const
1227 {
1228  float dx = GetPositionX() - x;
1229  float dy = GetPositionY() - y;
1230  float dz = GetPositionZ() - z;
1231  float sizefactor = GetObjectSize();
1232  float dist = dx * dx + dy * dy + dz * dz - sizefactor;
1233  return (dist > 0 ? dist : 0);
1234 }
1235 
1236 bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
1237 {
1238  float dx = GetPositionX() - obj->GetPositionX();
1239  float dy = GetPositionY() - obj->GetPositionY();
1240  float distsq = dx * dx + dy * dy;
1241  if (is3D)
1242  {
1243  float dz = GetPositionZ() - obj->GetPositionZ();
1244  distsq += dz * dz;
1245  }
1246  float sizefactor = GetObjectSize() + obj->GetObjectSize();
1247  float maxdist = dist2compare + sizefactor;
1248 
1249  return distsq < maxdist * maxdist;
1250 }
1251 
1253 {
1254  if (!IsInMap(obj))
1255  return false;
1256 
1257  float x, y, z;
1258  if (obj->GetTypeId() == TYPEID_PLAYER)
1259  obj->GetPosition(x, y, z);
1260  else
1261  obj->GetHitSpherePointFor(GetPosition(), x, y, z);
1262 
1263  return IsWithinLOS(x, y, z);
1264 }
1265 
1266 bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
1267 {
1268  if (IsInWorld())
1269  {
1270  float x, y, z;
1271  if (GetTypeId() == TYPEID_PLAYER)
1272  GetPosition(x, y, z);
1273  else
1274  GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
1275 
1276  return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f);
1277  }
1278 
1279  return true;
1280 }
1281 
1283 {
1284  G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
1285  G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
1286  G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * GetObjectSize();
1287 
1288  return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
1289 }
1290 
1291 void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const
1292 {
1293  Position pos = GetHitSpherePointFor(dest);
1294  x = pos.GetPositionX();
1295  y = pos.GetPositionY();
1296  z = pos.GetPositionZ();
1297 }
1298 
1299 bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const
1300 {
1301  float dx1 = GetPositionX() - obj1->GetPositionX();
1302  float dy1 = GetPositionY() - obj1->GetPositionY();
1303  float distsq1 = dx1 * dx1 + dy1 * dy1;
1304  if (is3D)
1305  {
1306  float dz1 = GetPositionZ() - obj1->GetPositionZ();
1307  distsq1 += dz1 * dz1;
1308  }
1309 
1310  float dx2 = GetPositionX() - obj2->GetPositionX();
1311  float dy2 = GetPositionY() - obj2->GetPositionY();
1312  float distsq2 = dx2 * dx2 + dy2 * dy2;
1313  if (is3D)
1314  {
1315  float dz2 = GetPositionZ() - obj2->GetPositionZ();
1316  distsq2 += dz2 * dz2;
1317  }
1318 
1319  return distsq1 < distsq2;
1320 }
1321 
1322 bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D /* = true */) const
1323 {
1324  float dx = GetPositionX() - obj->GetPositionX();
1325  float dy = GetPositionY() - obj->GetPositionY();
1326  float distsq = dx * dx + dy * dy;
1327  if (is3D)
1328  {
1329  float dz = GetPositionZ() - obj->GetPositionZ();
1330  distsq += dz * dz;
1331  }
1332 
1333  float sizefactor = GetObjectSize() + obj->GetObjectSize();
1334 
1335  // check only for real range
1336  if (minRange > 0.0f)
1337  {
1338  float mindist = minRange + sizefactor;
1339  if (distsq < mindist * mindist)
1340  return false;
1341  }
1342 
1343  float maxdist = maxRange + sizefactor;
1344  return distsq < maxdist * maxdist;
1345 }
1346 
1347 bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) const
1348 {
1349  float dx = GetPositionX() - x;
1350  float dy = GetPositionY() - y;
1351  float distsq = dx * dx + dy * dy;
1352 
1353  float sizefactor = GetObjectSize();
1354 
1355  // check only for real range
1356  if (minRange > 0.0f)
1357  {
1358  float mindist = minRange + sizefactor;
1359  if (distsq < mindist * mindist)
1360  return false;
1361  }
1362 
1363  float maxdist = maxRange + sizefactor;
1364  return distsq < maxdist * maxdist;
1365 }
1366 
1367 bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float maxRange) const
1368 {
1369  float dx = GetPositionX() - x;
1370  float dy = GetPositionY() - y;
1371  float dz = GetPositionZ() - z;
1372  float distsq = dx * dx + dy * dy + dz * dz;
1373 
1374  float sizefactor = GetObjectSize();
1375 
1376  // check only for real range
1377  if (minRange > 0.0f)
1378  {
1379  float mindist = minRange + sizefactor;
1380  if (distsq < mindist * mindist)
1381  return false;
1382  }
1383 
1384  float maxdist = maxRange + sizefactor;
1385  return distsq < maxdist * maxdist;
1386 }
1387 
1388 bool WorldObject::HasInArc(const float arcangle, const float x, const float y) const
1389 {
1390  // always have self in arc
1391  if (x == m_positionX && y == m_positionY)
1392  return true;
1393 
1394  float arc = arcangle;
1395 
1396  // move arc to range 0.. 2*pi
1397  while ( arc >= 2.0f * float(M_PI) )
1398  arc -= 2.0f * float(M_PI);
1399  while ( arc < 0 )
1400  arc += 2.0f * float(M_PI);
1401 
1402  float angle = GetAngle( x, y );
1403  angle -= GetOrientation();
1404 
1405  // move angle to range -pi ... +pi
1406  while ( angle > float(M_PI))
1407  angle -= 2.0f * float(M_PI);
1408  while (angle < -M_PI)
1409  angle += 2.0f * float(M_PI);
1410 
1411  float lborder = -1 * (arc / 2.0f); // in range -pi..0
1412  float rborder = (arc / 2.0f); // in range 0..pi
1413  return (( angle >= lborder ) && ( angle <= rborder ));
1414 }
1415 
1416 bool WorldObject::HasInArc(float arc, const Position* obj) const
1417 {
1418  return this->HasInArc(arc, obj->GetPositionX(), obj->GetPositionY());
1419 }
1420 
1421 void WorldObject::GetRandomPoint(const Position& pos, float distance, float& rand_x, float& rand_y, float& rand_z) const
1422 {
1423  if (!distance)
1424  {
1425  pos.GetPosition(rand_x, rand_y, rand_z);
1426  return;
1427  }
1428 
1429  // angle to face `obj` to `this`
1430  float angle = rand_norm() * 2 * M_PI;
1431  float new_dist = rand_norm() * distance;
1432 
1433  rand_x = pos.m_positionX + new_dist * cos(angle);
1434  rand_y = pos.m_positionY + new_dist * sin(angle);
1435  rand_z = pos.m_positionZ;
1436 
1437  Oregon::NormalizeMapCoord(rand_x);
1438  Oregon::NormalizeMapCoord(rand_y);
1439  UpdateGroundPositionZ(rand_x, rand_y, rand_z); // update to LOS height if available
1440 }
1441 
1442 void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
1443 {
1444  switch (GetTypeId())
1445  {
1446  case TYPEID_UNIT:
1447  {
1448  // non fly unit don't must be in air
1449  // non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
1450  if (!((Creature const*)this)->CanFly())
1451  {
1452  bool canSwim = ((Creature const*)this)->CanSwim();
1453  float ground_z = z;
1454  float max_z = canSwim
1455  ? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
1456  : ((ground_z = GetBaseMap()->GetHeight(x, y, z, true)));
1457  if (max_z > INVALID_HEIGHT)
1458  {
1459  if (z > max_z)
1460  z = max_z;
1461  else if (z < ground_z)
1462  z = ground_z;
1463  }
1464  }
1465  else
1466  {
1467  float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
1468  if (z < ground_z)
1469  z = ground_z;
1470  }
1471  break;
1472  }
1473  case TYPEID_PLAYER:
1474  {
1475  // for server controlled moves playr work same as creature (but it can always swim)
1476  if (!((Player const*)this)->CanFly())
1477  {
1478  float ground_z = z;
1479  float max_z = GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
1480  if (max_z > INVALID_HEIGHT)
1481  {
1482  if (z > max_z)
1483  z = max_z;
1484  else if (z < ground_z)
1485  z = ground_z;
1486  }
1487  }
1488  else
1489  {
1490  float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
1491  if (z < ground_z)
1492  z = ground_z;
1493  }
1494  break;
1495  }
1496  default:
1497  {
1498  float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
1499  if (ground_z > INVALID_HEIGHT)
1500  z = ground_z;
1501  break;
1502  }
1503  }
1504 }
1505 
1506 void WorldObject::UpdateGroundPositionZ(float x, float y, float& z) const
1507 {
1508  float new_z = GetBaseMap()->GetHeight(x, y, z, true);
1509  if (new_z > INVALID_HEIGHT)
1510  z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
1511 }
1512 
1513 void WorldObject::MonsterSay(const char* text, uint32 language, uint64 TargetGuid)
1514 {
1515  WorldPacket data(SMSG_MESSAGECHAT, 200);
1516  BuildMonsterChat(&data, CHAT_MSG_MONSTER_SAY, text, language, GetName(), TargetGuid);
1517  SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY), true);
1518 }
1519 
1520 void WorldObject::MonsterYell(const char* text, uint32 language, uint64 TargetGuid)
1521 {
1522  WorldPacket data(SMSG_MESSAGECHAT, 200);
1523  BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, text, language, GetName(), TargetGuid);
1524  SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL), true);
1525 }
1526 
1527 void WorldObject::MonsterTextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote)
1528 {
1529  WorldPacket data(SMSG_MESSAGECHAT, 200);
1530  BuildMonsterChat(&data, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, text, LANG_UNIVERSAL, GetName(), TargetGuid);
1532 }
1533 
1534 void WorldObject::MonsterWhisper(const char* text, uint64 receiver, bool IsBossWhisper)
1535 {
1536  Player* player = sObjectMgr.GetPlayer(receiver);
1537  if (!player || !player->GetSession())
1538  return;
1539 
1540  WorldPacket data(SMSG_MESSAGECHAT, 200);
1541  BuildMonsterChat(&data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, GetName(), receiver);
1542 
1543  player->GetSession()->SendPacket(&data);
1544 }
1545 
1547 {
1548  if (!IsInWorld())
1549  return false;
1550 
1551  return true;
1552 }
1553 
1555 {
1556  if (ToPlayer())
1557  {
1558  if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
1560  return GetMap()->GetVisibilityRange();
1561  }
1562  else if (ToCreature())
1563  return ToCreature()->m_SightDistance;
1564  else if (ToDynObject())
1565  {
1566  if (isActiveObject())
1567  return GetMap()->GetVisibilityRange();
1568  else
1569  return 0.0f;
1570  }
1571  else
1572  return 0.0f;
1573 }
1574 
1576 {
1577  if (IsVisibilityOverridden() && !ToPlayer())
1579  else if (isActiveObject() && !ToPlayer())
1580  return MAX_VISIBILITY_DISTANCE;
1581  else
1582  return GetMap()->GetVisibilityRange();
1583 }
1584 
1585 float WorldObject::GetSightRange(const WorldObject* target) const
1586 {
1587  if (ToUnit())
1588  {
1589  if (ToPlayer())
1590  {
1591  if (target && target->IsVisibilityOverridden() && !target->ToPlayer())
1592  return target->m_visibilityDistanceOverride;
1593  else if (target && target->isActiveObject() && !target->ToPlayer())
1594  return MAX_VISIBILITY_DISTANCE;
1595  else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
1597  else
1598  return GetMap()->GetVisibilityRange();
1599  }
1600  else if (ToCreature())
1601  return ToCreature()->m_SightDistance;
1602  else
1603  return SIGHT_RANGE_UNIT;
1604  }
1605 
1606  if (ToDynObject() && isActiveObject())
1607  return GetMap()->GetVisibilityRange();
1608 
1609  return 0.0f;
1610 }
1611 
1612 bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck, bool checkAlert) const
1613 {
1614  if (this == obj)
1615  return true;
1616 
1617  if (obj->IsNeverVisible() || CanNeverSee(obj))
1618  return false;
1619 
1620  if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj))
1621  return true;
1622 
1623  bool corpseVisibility = false;
1624  if (distanceCheck)
1625  {
1626  bool corpseCheck = false;
1627  if (const Player* thisPlayer = ToPlayer())
1628  {
1629  if (thisPlayer->isDead() && thisPlayer->GetHealth() > 0 && // Cheap way to check for ghost state
1631  {
1632  if (Corpse* corpse = thisPlayer->GetCorpse())
1633  {
1634  corpseCheck = true;
1635  if (corpse->IsWithinDist(thisPlayer, GetSightRange(obj), false))
1636  if (corpse->IsWithinDist(obj, GetSightRange(obj), false))
1637  corpseVisibility = true;
1638  }
1639  }
1640  }
1641 
1642  WorldObject const* viewpoint = this;
1643  if (Player const* player = this->ToPlayer())
1644  viewpoint = player->GetViewpoint();
1645 
1646  if (!viewpoint)
1647  viewpoint = this;
1648 
1649  if (!corpseCheck && !viewpoint->IsWithinDist(obj, GetSightRange(obj), false))
1650  return false;
1651  }
1652 
1653  // GM visibility off or hidden NPC
1655  {
1656  // Stop checking other things for GMs
1658  return true;
1659  }
1660  else
1662 
1663  // Ghost players, Spirit Healers, and some other NPCs
1665  {
1666  // Alive players can see dead players in some cases, but other objects can't do that
1667  if (const Player* thisPlayer = ToPlayer())
1668  {
1669  if (const Player* objPlayer = obj->ToPlayer())
1670  {
1671  if (thisPlayer->GetTeam() != objPlayer->GetTeam() || !thisPlayer->IsGroupVisibleFor(objPlayer))
1672  return false;
1673  }
1674  else
1675  return false;
1676  }
1677  else
1678  return false;
1679  }
1680 
1681  if (obj->IsInvisibleDueToDespawn())
1682  return false;
1683 
1684  if (!CanDetect(obj, ignoreStealth, checkAlert))
1685  return false;
1686 
1687  return true;
1688 }
1689 
1691 {
1692  return GetMap() != obj->GetMap() || !InSamePhase(obj);
1693 }
1694 
1695 bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert) const
1696 {
1697  const WorldObject* seer = this;
1698 
1699  // Pets don't have detection, they use the detection of their masters
1700  if (const Unit* thisUnit = ToUnit())
1701  if (Unit* controller = thisUnit->GetCharmerOrOwner())
1702  seer = controller;
1703 
1704  if (obj->IsAlwaysDetectableFor(seer))
1705  return true;
1706 
1707  if (!ignoreStealth && !seer->CanDetectInvisibilityOf(obj))
1708  return false;
1709 
1710  if (!ignoreStealth && !seer->CanDetectStealthOf(obj, checkAlert))
1711  return false;
1712 
1713  return true;
1714 }
1715 
1717 {
1719 
1720  // Check for not detected types
1721  if (mask != obj->m_invisibility.GetFlags())
1722  return false;
1723 
1724  // It isn't possible in invisibility to detect something that can't detect the invisible object
1725  // (it's at least true for spell: 66)
1726  // It seems like that only Units are affected by this check (couldn't see arena doors with preparation invisibility)
1727  if (obj->ToUnit())
1729  return false;
1730 
1731  for (uint32 i = 0; i < TOTAL_INVISIBILITY_TYPES; ++i)
1732  {
1733  if (!(mask & (1 << i)))
1734  continue;
1735 
1736  int32 objInvisibilityValue = obj->m_invisibility.GetValue(InvisibilityType(i));
1737  int32 ownInvisibilityDetectValue = m_invisibilityDetect.GetValue(InvisibilityType(i));
1738 
1739  // Too low value to detect
1740  if (ownInvisibilityDetectValue < objInvisibilityValue)
1741  return false;
1742  }
1743 
1744  return true;
1745 }
1746 
1747 bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) const
1748 {
1749  // Combat reach is the minimal distance (both in front and behind),
1750  // and it is also used in the range calculation.
1751  // One stealth point increases the visibility range by 0.3 yard.
1752 
1753  if (!obj->m_stealth.GetFlags())
1754  return true;
1755 
1756  float distance = GetExactDist(obj);
1757  float combatReach = 0.0f;
1758 
1759  Unit const* unit = ToUnit();
1760  if (unit)
1761  combatReach = unit->GetCombatReach();
1762 
1763  if (distance < combatReach)
1764  return true;
1765 
1766  if (!HasInArc(float(M_PI), obj))
1767  return false;
1768 
1769  GameObject const* go = obj->ToGameObject();
1770  for (uint32 i = 0; i < TOTAL_STEALTH_TYPES; ++i)
1771  {
1772  if (!(obj->m_stealth.GetFlags() & (1 << i)))
1773  continue;
1774 
1776  return true;
1777 
1778  // Starting points
1779  int32 detectionValue = 30;
1780 
1781  // Level difference: 5 point / level, starting from level 1.
1782  // There may be spells for this and the starting points too, but
1783  // not in the DBCs of the client.
1784  detectionValue += int32(getLevelForTarget(obj) - 1) * 5;
1785 
1786  // Apply modifiers
1787  detectionValue += m_stealthDetect.GetValue(StealthType(i));
1788  if (go)
1789  if (Unit* owner = go->GetOwner())
1790  detectionValue -= int32(owner->getLevelForTarget(this) - 1) * 5;
1791 
1792  detectionValue -= obj->m_stealth.GetValue(StealthType(i));
1793 
1794  // Calculate max distance
1795  float visibilityRange = float(detectionValue) * 0.3f + combatReach;
1796 
1797  // If this unit is an NPC then player detect range doesn't apply
1798  if (unit && unit->GetTypeId() == TYPEID_PLAYER && visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE)
1799  visibilityRange = MAX_PLAYER_STEALTH_DETECT_RANGE;
1800 
1801  // When checking for alert state, look 8% further, and then 1.5 yards more than that.
1802  if (checkAlert)
1803  visibilityRange += (visibilityRange * 0.08f) + 1.5f;
1804 
1805  // If checking for alert, and creature's visibility range is greater than aggro distance, No alert
1806  Unit const* tunit = obj->ToUnit();
1807  if (checkAlert && unit && unit->ToCreature() && visibilityRange >= unit->ToCreature()->GetAttackDistance(tunit) + unit->ToCreature()->m_CombatDistance)
1808  return false;
1809 
1810  if (distance > visibilityRange)
1811  return false;
1812  }
1813 
1814  return true;
1815 }
1816 
1817 void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf)
1818 {
1819  WorldPacket data(SMSG_PLAY_SOUND, 4);
1820  data << Sound;
1821  if (OnlySelf && GetTypeId() == TYPEID_PLAYER)
1822  ToPlayer()->GetSession()->SendPacket(&data);
1823  else
1824  SendMessageToSet(&data, true); // ToSelf ignored in this case
1825 }
1826 
1828 {
1829  m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed
1830  if (m_inWorld)
1831  {
1832  if (!m_objectUpdated)
1833  {
1835  m_objectUpdated = true;
1836  }
1837  }
1838 }
1839 
1840 namespace Oregon
1841 {
1843 {
1844  public:
1845  MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID)
1846  : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_targetGUID(targetGUID) {}
1847  void operator()(WorldPacket& data, int32 loc_idx)
1848  {
1849  char const* text = sObjectMgr.GetOregonString(i_textId, loc_idx);
1850 
1851  // @todo i_object.GetName() also must be localized?
1852  i_object.BuildMonsterChat(&data, i_msgtype, text, i_language, i_object.GetNameForLocaleIdx(loc_idx), i_targetGUID);
1853  }
1854 
1855  private:
1861 };
1862 } // namespace Oregon
1863 
1864 void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
1865 {
1867 
1868  Cell cell(p);
1869  cell.SetNoCreate();
1870 
1871  Oregon::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId, language, TargetGuid);
1875  cell.Visit(p, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
1876 }
1877 
1878 void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
1879 {
1881 
1882  Cell cell(p);
1883  cell.SetNoCreate();
1884 
1885  Oregon::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId, language, TargetGuid);
1889  cell.Visit(p, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
1890 }
1891 
1892 void WorldObject::MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
1893 {
1894  Oregon::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId, language, TargetGuid);
1896 
1897  uint32 zoneid = GetZoneId();
1898 
1899  Map::PlayerList const& pList = GetMap()->GetPlayers();
1900  for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
1901  if (itr->GetSource()->GetZoneId() == zoneid)
1902  say_do(itr->GetSource());
1903 }
1904 
1905 void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote)
1906 {
1908 
1909  Cell cell(p);
1910  cell.SetNoCreate();
1911 
1912  Oregon::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId, LANG_UNIVERSAL, TargetGuid);
1916  cell.Visit(p, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
1917 }
1918 
1919 void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper)
1920 {
1921  Player* player = sObjectMgr.GetPlayer(receiver);
1922  if (!player || !player->GetSession())
1923  return;
1924 
1925  uint32 loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
1926  char const* text = sObjectMgr.GetOregonString(textId, loc_idx);
1927 
1928  WorldPacket data(SMSG_MESSAGECHAT, 200);
1929  BuildMonsterChat(&data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, GetName(), receiver);
1930 
1931  player->GetSession()->SendPacket(&data);
1932 }
1933 
1934 void WorldObject::BuildMonsterChat(WorldPacket* data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 targetGuid) const
1935 {
1936  *data << (uint8)msgtype;
1937  *data << (uint32)language;
1938  *data << (uint64)GetGUID();
1939  *data << (uint32)0; //2.1.0
1940  *data << (uint32)(strlen(name) + 1);
1941  *data << name;
1942  *data << (uint64)targetGuid; //Unit Target
1943  if (targetGuid && !IS_PLAYER_GUID(targetGuid))
1944  {
1945  *data << (uint32)1; // target name length
1946  *data << (uint8)0; // target name
1947  }
1948  *data << (uint32)(strlen(text) + 1);
1949  *data << text;
1950  *data << (uint8)0; // ChatTag
1951 }
1952 
1954 {
1955  data->Initialize(MSG_MOVE_HEARTBEAT, 32);
1956  *data << GetPackGUID();
1957  BuildMovementPacket(data);
1958 }
1959 
1960 void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*bToSelf*/)
1961 {
1962  Oregon::MessageDistDeliverer notifier(this, data, dist);
1963  VisitNearbyWorldObject(dist, notifier);
1964 }
1965 
1967 {
1969  data << uint64(guid);
1970  SendMessageToSet(&data, true);
1971 }
1972 
1974 {
1976  data << uint64(guid);
1977  data << uint32(anim);
1978  SendMessageToSet(&data, true);
1979 }
1980 
1982 {
1983  ASSERT(map);
1985  if (m_currMap == map) // command add npc: first create, than loadfromdb
1986  return;
1987  if (m_currMap)
1988  {
1989  sLog.outError("Crash alert! WorldObject::SetMap: obj %u new map %u %u, old map %u %u", (uint32)GetTypeId(), map->GetId(), map->GetInstanceId(), m_currMap->GetId(), m_currMap->GetInstanceId());
1990  ASSERT(false);
1991  }
1992  m_currMap = map;
1993  m_mapId = map->GetId();
1994  m_InstanceId = map->GetInstanceId();
1995  if (IsWorldObject())
1996  m_currMap->AddWorldObject(this);
1997 }
1998 
2000 {
2001  ASSERT(m_currMap);
2002  ASSERT(!IsInWorld());
2003  if (IsWorldObject())
2005  m_currMap = NULL;
2006  //maybe not for corpse
2007  //m_mapId = 0;
2008  //m_InstanceId = 0;
2009 }
2010 
2012 {
2013  ASSERT(m_currMap);
2014  return m_currMap->GetParent();
2015 }
2016 
2018 {
2020 
2021  Map* map = FindMap();
2022  if (!map)
2023  {
2024  sLog.outError("Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list has invalid map (Id: %u).", GetTypeId(), GetEntry(), GetGUIDLow(), GetMapId());
2025  return;
2026  }
2027 
2028  map->AddObjectToRemoveList(this);
2029 }
2030 
2031 TempSummon* Map::SummonCreature(uint32 entry, const Position& pos, SummonPropertiesEntry const* properties, uint32 duration, Unit* summoner, uint32 spellId, TempSummonType spwType)
2032 {
2033  uint32 mask = UNIT_MASK_SUMMON;
2034  if (properties)
2035  {
2036  switch (properties->Category)
2037  {
2038  case SUMMON_CATEGORY_PET:
2039  mask = UNIT_MASK_GUARDIAN;
2040  break;
2042  mask = UNIT_MASK_PUPPET;
2043  break;
2044  case SUMMON_CATEGORY_WILD:
2045  case SUMMON_CATEGORY_ALLY:
2046  {
2047  switch (properties->Type)
2048  {
2049  case SUMMON_TYPE_MINION:
2050  case SUMMON_TYPE_GUARDIAN:
2051  case SUMMON_TYPE_GUARDIAN2:
2052  mask = UNIT_MASK_GUARDIAN;
2053  break;
2054  case SUMMON_TYPE_TOTEM:
2055  mask = UNIT_MASK_TOTEM;
2056  break;
2057  case SUMMON_TYPE_MINIPET:
2058  mask = UNIT_MASK_MINION;
2059  break;
2060  default:
2061  if (properties->Flags & 512)
2062  mask = UNIT_MASK_GUARDIAN;
2063  break;
2064  }
2065  break;
2066  }
2067  default:
2068  return NULL;
2069  }
2070  }
2071 
2072  uint32 team = 0;
2073  if (summoner && summoner->GetTypeId() == TYPEID_PLAYER)
2074  team = summoner->ToPlayer()->GetTeam();
2075 
2076  TempSummon* summon = NULL;
2077  switch (mask)
2078  {
2079  case UNIT_MASK_SUMMON:
2080  summon = new TempSummon(properties, summoner, false);
2081  break;
2082  case UNIT_MASK_GUARDIAN:
2083  summon = new Guardian(properties, summoner, false);
2084  break;
2085  case UNIT_MASK_PUPPET:
2086  summon = new Puppet(properties, summoner);
2087  break;
2088  case UNIT_MASK_TOTEM:
2089  summon = new Totem(properties, summoner);
2090  break;
2091  case UNIT_MASK_MINION:
2092  summon = new Minion(properties, summoner, false);
2093  break;
2094  default:
2095  return NULL;
2096  }
2097 
2098  if (!summon->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT), this, PHASEMASK_NORMAL, entry, team, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
2099  {
2100  delete summon;
2101  return NULL;
2102  }
2103 
2104  summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
2105  summon->SetHomePosition(pos);
2106  // CreatureAI::Reset was already called, check if TempSummonType changed, if
2107  // so, don't touch it or we may mess up the script. (Example Script: Inferno)
2108  // TEMPSUMMON_MANUL_DESPAWN is the default one so we check against it.
2110  summon->SetTempSummonType(spwType);
2111  summon->InitStats(duration);
2112  AddToMap(summon->ToCreature());
2113  summon->InitSummon();
2114 
2115  return summon;
2116 }
2117 
2119 {
2120  if (Map* map = FindMap())
2121  {
2122  if (TempSummon* summon = map->SummonCreature(entry, pos, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL, NULL, spwtype))
2123  return summon;
2124  }
2125 
2126  return NULL;
2127 }
2128 
2130 {
2131  if (Map* map = FindMap())
2132  {
2133  if (map->IsDungeon())
2134  m_zoneScript = (ZoneScript*)((InstanceMap*)map)->GetInstanceData();
2135  else if (!map->IsBattlegroundOrArena())
2136  m_zoneScript = sOutdoorPvPMgr.GetZoneScript(GetZoneId());
2137  }
2138 }
2139 
2140 Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration)
2141 {
2142  Pet* pet = new Pet(this, petType);
2143  SetPetStatus(PET_STATUS_CURRENT);
2144 
2145  if (petType == SUMMON_PET && pet->LoadPetFromDB(this, entry))
2146  {
2147  // Remove Demonic Sacrifice auras (known pet)
2148  Unit::AuraList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
2149  for (Unit::AuraList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();)
2150  {
2151  if ((*itr)->GetModifier()->m_miscvalue == 2228)
2152  {
2153  RemoveAurasDueToSpell((*itr)->GetId());
2154  itr = auraClassScripts.begin();
2155  }
2156  else
2157  ++itr;
2158  }
2159 
2160  if (duration > 0)
2161  pet->SetDuration(duration);
2162 
2163  return NULL;
2164  }
2165 
2166  // petentry == 0 for hunter "call pet" (current pet summoned if any)
2167  if (!entry)
2168  {
2169  delete pet;
2170  return NULL;
2171  }
2172 
2173  Map* map = GetMap();
2174  uint32 pet_number = sObjectMgr.GeneratePetNumber();
2175  if (!pet->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_PET), map, GetPhaseMask(), entry, pet_number))
2176  {
2177  sLog.outError("no such creature entry %u", entry);
2178  delete pet;
2179  return NULL;
2180  }
2181 
2182  pet->Relocate(x, y, z, ang);
2183  if (!pet->IsPositionValid())
2184  {
2185  sLog.outError("Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)", pet->GetGUIDLow(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY());
2186  delete pet;
2187  return NULL;
2188  }
2189 
2190  pet->SetCreatorGUID(GetGUID());
2191  pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, GetFaction());
2192 
2193  // this enables pet details window (Shift+P)
2194  pet->GetCharmInfo()->SetPetNumber(pet_number, false);
2195 
2196  pet->setPowerType(POWER_MANA);
2197  pet->SetUInt32Value(UNIT_NPC_FLAGS , 0);
2199  pet->InitStatsForLevel(getLevel());
2200 
2201  SetMinion(pet, true);
2202 
2203  switch (petType)
2204  {
2205  case CLASS_PET:
2206  case SUMMON_PET:
2207  pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
2210  pet->SetHealth(pet->GetMaxHealth());
2213  default:
2214  break;
2215  }
2216 
2217  map->AddToMap(pet->ToCreature());
2218 
2219  switch (petType)
2220  {
2221  case CLASS_PET:
2222  case SUMMON_PET:
2223  pet->InitPetCreateSpells();
2225  PetSpellInitialize();
2226  default:
2227  break;
2228  }
2229 
2230  if (petType == SUMMON_PET)
2231  {
2232  // Remove Demonic Sacrifice auras (known pet)
2233  Unit::AuraList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
2234  for (Unit::AuraList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();)
2235  {
2236  if ((*itr)->GetModifier()->m_miscvalue == 2228)
2237  {
2238  RemoveAurasDueToSpell((*itr)->GetId());
2239  itr = auraClassScripts.begin();
2240  }
2241  else
2242  ++itr;
2243  }
2244  }
2245 
2246  if (duration > 0)
2247  pet->SetDuration(duration);
2248 
2249  return pet;
2250 }
2251 
2252 GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
2253 {
2254  if (!IsInWorld())
2255  return NULL;
2256 
2257  GameObjectInfo const* goinfo = sObjectMgr.GetGameObjectInfo(entry);
2258  if (!goinfo)
2259  {
2260  sLog.outErrorDb("Gameobject template %u not found in database!", entry);
2261  return NULL;
2262  }
2263  Map* map = GetMap();
2264  GameObject* go = new GameObject();
2265  if (!go->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, PHASEMASK_NORMAL, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY))
2266  {
2267  delete go;
2268  return NULL;
2269  }
2270  go->SetRespawnTime(respawnTime);
2271  if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT) //not sure how to handle this
2272  ((Unit*)this)->AddGameObject(go);
2273  else
2274  go->SetSpawnedByDefault(false);
2275  map->AddToMap(go);
2276 
2277  return go;
2278 }
2279 
2280 Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint32 duration, CreatureAI * (*GetAI)(Creature*))
2281 {
2282  TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2283  Creature* summon = SummonCreature(WORLD_TRIGGER, x, y, z, ang, summonType, duration);
2284  if (!summon)
2285  return NULL;
2286 
2287  //summon->SetName(GetName());
2288  if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT)
2289  {
2290  summon->SetFaction(((Unit*)this)->GetFaction());
2291  summon->SetLevel(((Unit*)this)->getLevel());
2292  }
2293 
2294  if (GetAI)
2295  summon->AIM_Initialize(GetAI(summon));
2296  return summon;
2297 }
2298 
2305 void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= NULL*/)
2306 {
2307  ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!");
2308 
2309  std::vector<TempSummonData> const* data = sObjectMgr.GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group);
2310  if (!data)
2311  return;
2312 
2313  for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
2314  if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, itr->time))
2315  if (list)
2316  list->push_back(summon);
2317 }
2318 
2319 Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive)
2320 {
2321  Creature* creature = NULL;
2322  Oregon::NearestCreatureEntryWithLiveStateInObjectRangeCheck checker(*this, entry, alive, range);
2324  VisitNearbyObject(range, searcher);
2325  return creature;
2326 }
2327 
2329 {
2330  GameObject* go = NULL;
2331  Oregon::NearestGameObjectEntryInObjectRangeCheck checker(*this, entry, range);
2333  VisitNearbyGridObject(range, searcher);
2334  return go;
2335 }
2336 
2338 {
2339  GameObject* go = NULL;
2340  Oregon::NearestGameObjectTypeInObjectRangeCheck checker(*this, type, range);
2342  VisitNearbyGridObject(range, searcher);
2343  return go;
2344 }
2345 
2346 void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameobjectList, uint32 entry, float maxSearchRange) const
2347 {
2349  Cell cell(pair);
2350  cell.SetNoCreate();
2351 
2352  Oregon::AllGameObjectsWithEntryInRange check(this, entry, maxSearchRange);
2353  Oregon::GameObjectListSearcher<Oregon::AllGameObjectsWithEntryInRange> searcher(this, gameobjectList, check);
2355 
2356  cell.Visit(pair, visitor, *(this->GetMap()), *this, maxSearchRange);
2357 }
2358 
2359 void WorldObject::GetCreatureListWithEntryInGrid(std::list<Creature*>& creatureList, uint32 entry, float maxSearchRange) const
2360 {
2362  Cell cell(pair);
2363  cell.SetNoCreate();
2364 
2365  Oregon::AllCreaturesOfEntryInRange check(this, entry, maxSearchRange);
2366  Oregon::CreatureListSearcher<Oregon::AllCreaturesOfEntryInRange> searcher(this, creatureList, check);
2368 
2369  cell.Visit(pair, visitor, *(this->GetMap()), *this, maxSearchRange);
2370 }
2371 
2372 void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float absAngle) const
2373 {
2374  x = GetPositionX() + (GetObjectSize() + distance2d) * cos(absAngle);
2375  y = GetPositionY() + (GetObjectSize() + distance2d) * sin(absAngle);
2376 
2379 }
2380 
2381 void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle) const
2382 {
2383  GetNearPoint2D(x, y, distance2d + searcher_size, absAngle);
2384  z = GetPositionZ();
2385  UpdateAllowedPositionZ(x, y, z);
2386 
2387  // return if the point is already in LoS
2388  if (IsWithinLOS(x, y, z))
2389  return;
2390 
2391  // remember first point
2392  float first_x = x;
2393  float first_y = y;
2394  float first_z = z;
2395 
2396  // loop in a circle to look for a point in LoS using small steps
2397  for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8)
2398  {
2399  GetNearPoint2D(x, y, distance2d + searcher_size, absAngle);
2400  z = GetPositionZ();
2401  UpdateAllowedPositionZ(x, y, z);
2402  if (IsWithinLOS(x, y, z))
2403  return;
2404  }
2405 
2406  // still not in LoS, give up and return first position found
2407  x = first_x;
2408  y = first_y;
2409  z = first_z;
2410 }
2411 
2412 Position WorldObject::GetNearPosition(float dist, float angle)
2413 {
2414  Position pos = GetPosition();
2415  MovePosition(pos, dist, angle);
2416  return pos;
2417 }
2418 
2420 {
2421  Position pos = GetPosition();
2422  MovePositionToFirstCollision(pos, dist, angle);
2423  return pos;
2424 }
2425 
2427 {
2428  Position pos = GetPosition();
2429  MovePosition(pos, radius * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI));
2430  return pos;
2431 }
2432 
2433 // @todo: replace with WorldObject::UpdateAllowedPositionZ
2434 // To use WorldObject::UpdateAllowedPositionZ at the moment causes a caster of
2435 // a leap effect to fall through the ground much too easily.
2436 float WorldObject::GetPositionZTarget(Position& pos, float destx, float desty)
2437 {
2438 
2439  // Added in Bitbucket issue #1105 in order to solve the problem of
2440  // leap effects like Blink taking the caster to the bottom of a body of liquid.
2441 
2442  float bottom, ground, floor;
2443 
2444  ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
2445  floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
2446  // If we were to ignore liquid, the WorldObject would be placed here.
2447  bottom = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
2448 
2449  if(pos.m_positionZ > bottom)
2450  {
2451 
2452  // We are in the water or in the air.
2453  // Must be at least above ground.
2454 
2455  LiquidData dest_status;
2456  GetMap()->getLiquidStatus(destx, desty, pos.m_positionZ, MAP_ALL_LIQUIDS, &dest_status);
2457 
2458  // Source and destination are underwater.
2459  if(dest_status.level > pos.m_positionZ)
2460  return pos.m_positionZ;
2461 
2462  // When in doubt, send the user to water/ground level.
2463  return fabs(dest_status.level - pos.m_positionZ) <= fabs(bottom - pos.m_positionZ) ? dest_status.level : bottom;
2464 
2465  }
2466  else
2467  {
2468  // Destination is on or under the ground. Use ground Z.
2469  return bottom;
2470  }
2471 }
2472 
2473 void WorldObject::MovePosition(Position& pos, float dist, float angle)
2474 {
2475  angle += GetOrientation();
2476  float destx, desty, destz, ground, floor;
2477  destx = pos.m_positionX + dist * cos(angle);
2478  desty = pos.m_positionY + dist * sin(angle);
2479 
2480  // Prevent invalid coordinates here, position is unchanged
2481  if (!Oregon::IsValidMapCoord(destx, desty, pos.m_positionZ))
2482  {
2483  sLog.outString("WorldObject::MovePosition invalid coordinates X: %f and Y: %f were passed!", destx, desty);
2484  return;
2485  }
2486 
2487  // Prevent invalid coordinates here, position is unchanged
2488  if (!Oregon::IsValidMapCoord(destx, desty))
2489  {
2490  sLog.outError("Crash alert! WorldObject::MovePositionToFirstCollision invalid coordinates X: %f and Y: %f were passed!", destx, desty);
2491  return;
2492  }
2493 
2494  ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
2495  floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
2496  destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
2497 
2498  float step = dist / 10.0f;
2499 
2500  for (uint8 j = 0; j < 10; ++j)
2501  {
2502  // do not allow too big z changes
2503  if (fabs(pos.m_positionZ - destz) > 6)
2504  {
2505  destx -= step * cos(angle);
2506  desty -= step * sin(angle);
2507  ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
2508  floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
2509  destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
2510  }
2511  // we have correct destz now
2512  else
2513  {
2514  pos.Relocate(destx, desty, destz);
2515  break;
2516  }
2517  }
2518 
2523 }
2524 
2525 void WorldObject::MovePositionToFirstCollision(Position& pos, float dist, float angle)
2526 {
2527  angle += GetOrientation();
2528  float destx, desty, destz;
2529  destx = pos.m_positionX + dist * cos(angle);
2530  desty = pos.m_positionY + dist * sin(angle);
2531 
2532  // Prevent invalid coordinates here, position is unchanged
2533  if (!Oregon::IsValidMapCoord(destx, desty))
2534  {
2535  sLog.outFatal("WorldObject::MovePositionToFirstCollision invalid coordinates X: %f and Y: %f were passed!", destx, desty);
2536  return;
2537  }
2538 
2539  destz = GetPositionZTarget(pos, destx, desty);
2540  bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
2541 
2542  // collision occured
2543  if (col)
2544  {
2545  // move back a bit
2546  destx -= CONTACT_DISTANCE * cos(angle);
2547  desty -= CONTACT_DISTANCE * sin(angle);
2548  dist = sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
2549  }
2550 
2551  // check dynamic collision
2552  col = GetMap()->getObjectHitPos(pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
2553 
2554  // Collided with a gameobject
2555  if (col)
2556  {
2557  destx -= CONTACT_DISTANCE * cos(angle);
2558  desty -= CONTACT_DISTANCE * sin(angle);
2559  dist = sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
2560  }
2561 
2562  float step = dist / 10.0f;
2563 
2564  for (uint8 j = 0; j < 10; ++j)
2565  {
2566  // do not allow too big z changes
2567  if (fabs(pos.m_positionZ - destz) > 6.0f)
2568  {
2569  destx -= step * cos(angle);
2570  desty -= step * sin(angle);
2571  destz = GetPositionZTarget(pos, destx, desty);
2572  }
2573  // we have correct destz now
2574  else
2575  {
2576  pos.Relocate(destx, desty, destz);
2577  break;
2578  }
2579  }
2580 
2583  pos.m_positionZ = GetPositionZTarget(pos, destx, desty);
2585 }
2586 
2587 void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
2588 {
2589  m_phaseMask = newPhaseMask;
2590 
2591  if (update && IsInWorld())
2593 }
2594 
2595 void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
2596 {
2597  WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8);
2598  data << uint32(sound_id);
2599  data << uint64(GetGUID());
2600  if (target)
2601  target->SendDirectMessage(&data);
2602  else
2603  SendMessageToSet(&data, true);
2604 }
2605 
2606 void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/)
2607 {
2608  WorldPacket data(SMSG_PLAY_SOUND, 4);
2609  data << uint32(sound_id);
2610  if (target)
2611  target->SendDirectMessage(&data);
2612  else
2613  SendMessageToSet(&data, true);
2614 }
2615 
2617 {
2618  if (!IsInWorld())
2619  return;
2620 
2621  std::list<Player*> targets;
2625  for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
2626  {
2627  Player* player = (*iter);
2628 
2629  if (player == this)
2630  continue;
2631 
2632  if (!player->HaveAtClient(this))
2633  continue;
2634 
2635  if (isType(TYPEMASK_UNIT) && ((Unit*)this)->GetCharmerGUID() == player->GetGUID()) // @todo this is for puppet
2636  continue;
2637 
2638  if (GetTypeId() == TYPEID_UNIT)
2639  {
2640  // at remove from world (destroy) show kill animation
2641  DestroyForPlayer(player, ToUnit()->IsDuringRemoveFromWorld() && ToCreature()->isDead());
2642  }
2643  else
2644  DestroyForPlayer(player);
2645 
2646  player->m_clientGUIDs.erase(GetGUID());
2647  }
2648 }
2649 
2651 {
2652  //updates object's visibility for nearby players
2653  Oregon::VisibleChangesNotifier notifier(*this);
2655 }
2656 
2658 {
2661  std::set<uint64> plr_list;
2662  WorldObjectChangeAccumulator(WorldObject& obj, UpdateDataMapType& d) : i_updateDatas(d), i_object(obj) {}
2664  {
2665  for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
2666  {
2667  BuildPacket(iter->GetSource());
2668  if (!iter->GetSource()->GetSharedVisionList().empty())
2669  {
2670  SharedVisionList::const_iterator it = iter->GetSource()->GetSharedVisionList().begin();
2671  for (; it != iter->GetSource()->GetSharedVisionList().end(); ++it)
2672  BuildPacket(*it);
2673  }
2674  }
2675  }
2676 
2678  {
2679  for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
2680  {
2681  if (!iter->GetSource()->GetSharedVisionList().empty())
2682  {
2683  SharedVisionList::const_iterator it = iter->GetSource()->GetSharedVisionList().begin();
2684  for (; it != iter->GetSource()->GetSharedVisionList().end(); ++it)
2685  BuildPacket(*it);
2686  }
2687  }
2688  }
2690  {
2691  for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
2692  {
2693  uint64 guid = iter->GetSource()->GetCasterGUID();
2694  if (IS_PLAYER_GUID(guid))
2695  {
2696  //Caster may be NULL if DynObj is in removelist
2697  if (Player* caster = ObjectAccessor::FindPlayer(guid))
2698  if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->GetSource()->GetGUID())
2699  BuildPacket(caster);
2700  }
2701  }
2702  }
2703  void BuildPacket(Player* plr)
2704  {
2705  // Only send update once to a player
2706  if (plr_list.find(plr->GetGUID()) == plr_list.end() && plr->HaveAtClient(&i_object))
2707  {
2708  i_object.BuildFieldsUpdate(plr, i_updateDatas);
2709  plr_list.insert(plr->GetGUID());
2710  }
2711  }
2712 
2713  template<class SKIP> void Visit(GridRefManager<SKIP>&) {}
2714 };
2715 
2717 {
2719  Cell cell(p);
2720  cell.SetNoCreate();
2721  WorldObjectChangeAccumulator notifier(*this, data_map);
2723  Map& map = *GetMap();
2724  //we must build packets for all visible players
2725  cell.Visit(p, player_notifier, map, *this, GetVisibilityRange());
2726 
2727  ClearUpdateMask(false);
2728 }
2729 
despawns when UnSummon() is called
float GetGridActivationRange() const
Definition: Object.cpp:1554
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2473
GameobjectTypes
bool BuildPacket(WorldPacket *packet, bool hasTransport=false)
Definition: UpdateData.cpp:103
virtual void ResetMap()
Definition: Object.cpp:1999
bool AddToMap(T *)
Definition: Map.cpp:424
void RemoveUpdateObject(Object *obj)
ClientGUIDs m_clientGUIDs
Definition: Player.h:2459
void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask)
Definition: Object.cpp:1185
void SetStatFloatValue(uint16 index, float value)
Definition: Object.cpp:928
GameObject * SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
Definition: Object.cpp:2252
void SendPlaySound(uint32 Sound, bool OnlySelf)
Definition: Object.cpp:1817
Definition: Corpse.h:48
PetType
Definition: Pet.h:25
float s_pitch
Definition: Object.h:440
const bool m_isWorldObject
Definition: Object.h:896
T_FLAGS GetFlags() const
Definition: Object.h:596
bool GetBit(uint32 index)
Definition: UpdateMask.h:49
bool m_objectUpdated
Definition: Object.h:416
const uint32 & GetUInt32Value(uint16 index) const
Definition: Object.h:210
virtual bool IsNeverVisible() const
Definition: Object.h:792
Unit * GetOwner() const
Definition: GameObject.cpp:799
void ApplyModUInt32Value(uint16 index, int32 val, bool apply)
Definition: Object.cpp:944
void _BuildMovementUpdate(ByteBuffer *data, uint8 updateFlags) const
Definition: Object.cpp:253
Map * m_currMap
Definition: Object.h:913
virtual void SetPhaseMask(uint32 newPhaseMask, bool update)
Definition: Object.cpp:2587
void ClearUpdateMask(bool remove)
Definition: Object.cpp:676
void SetPetNumber(uint32 petnumber, bool statwindow)
Definition: Unit.cpp:11428
uint32 GetMaxHealth() const
Definition: Unit.h:1075
bool m_inWorld
Definition: Object.h:419
bool _IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D) const
Definition: Object.cpp:1236
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1299
uint32 * m_uint32Values
Definition: Object.h:408
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:79
void PlayDirectSound(uint32 sound_id, Player *target=NULL)
Definition: Object.cpp:2606
float GetTransOffsetZ() const
Definition: Player.h:2408
int32 * m_int32Values
Definition: Object.h:407
Map * GetMap() const
Definition: Object.h:817
std::vector< std::string > Tokens
Definition: Util.h:26
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime)
Definition: Object.cpp:2140
void SendObjectCustomAnim(uint64 guid, uint32 anim=0)
Definition: Object.cpp:1973
#define DEFAULT_VISIBILITY_INSTANCE
Definition: Object.h:46
uint32 GetFaction() const
Definition: Unit.h:1116
bool IsVisibilityOverridden() const
Definition: Object.h:877
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const
Definition: Unit.cpp:883
uint32 GetUnitMovementFlags() const
Definition: Unit.h:1907
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition: Object.cpp:2337
void Visit(DynamicObjectMapType &m)
Definition: Object.cpp:2689
void MonsterTextEmote(const char *text, uint64 TargetGuid, bool IsBossEmote=false)
Definition: Object.cpp:1527
Position GetFirstCollisionPosition(float dist, float angle)
Definition: Object.cpp:2419
void MonsterSay(const char *text, uint32 language, uint64 TargetGuid)
Definition: Object.cpp:1513
float m_positionY
Definition: Position.h:51
float GetDistanceSqr(float x, float y, float z) const
Definition: Object.cpp:1226
bool LoadValues(const char *data)
Definition: Object.cpp:702
void SetOrientation(float orientation)
Definition: Position.h:92
void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target) const
Definition: Object.cpp:450
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition: Object.cpp:218
MovementInfo m_movementInfo
Definition: Object.h:890
void BuildFieldsUpdate(Player *, UpdateDataMapType &) const
Definition: Object.cpp:688
void SetInt32Value(uint16 index, int32 value)
Definition: Object.cpp:758
std::set< uint64 > plr_list
Definition: Object.cpp:2661
#define VISIBILITY_DISTANCE_LARGE
Definition: Object.h:41
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1442
bool isType(uint16 mask) const
Definition: Object.h:193
void setActive(bool isActiveObject)
Definition: Object.cpp:1122
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition: Object.h:809
#define WORLD_TRIGGER
Definition: Unit.h:38
uint32 GetZoneId() const
Definition: Object.cpp:1202
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0)
Definition: Object.cpp:2118
void BuildMovementUpdateBlock(UpdateData *data, uint32 flags=0) const
Definition: Object.cpp:136
void ApplyModInt32Value(uint16 index, int32 val, bool apply)
Definition: Object.cpp:953
virtual void SetMap(Map *map)
Definition: Object.cpp:1981
bool CanNeverSee(WorldObject const *obj) const
Definition: Object.cpp:1690
uint32 getMSTime()
Definition: Timer.h:32
void _LoadIntoDataField(const char *data, uint32 startOffset, uint32 count)
Definition: Object.cpp:719
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition: Map.cpp:1591
void SetValue(FLAG_TYPE flag, T_VALUES value)
Definition: Object.h:602
#define sLog
Log class singleton.
Definition: Log.h:187
float GetVisibilityRange() const
Definition: Object.cpp:1575
ChatMsg
virtual void CleanupsBeforeDelete()
Definition: Object.cpp:1179
Transport * GetTransport() const
Definition: Player.h:2391
void GetCreatureListWithEntryInGrid(std::list< Creature * > &creatureList, uint32 entry=GRID_SEARCH_ALL_ENTRIES, float maxSearchRange=250.0f) const
Definition: Object.cpp:2359
Tokens StrSplit(const std::string &src, const std::string &sep)
Definition: Util.cpp:58
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:777
ACE_INT32 int32
Definition: Define.h:67
bool IsWithinLOSInMap(const WorldObject *obj) const
Definition: Object.cpp:1252
std::list< Aura * > AuraList
Definition: Unit.h:917
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:727
NULL Dbg ErrDB Arena Chat Char Map MMap false
Definition: Log.cpp:556
bool IsValidMapCoord(float c)
Definition: GridDefines.h:192
void GetGameObjectListWithEntryInGrid(std::list< GameObject * > &gameobjectList, uint32 entry=GRID_SEARCH_ALL_ENTRIES, float maxSearchRange=250.0f) const
Definition: Object.cpp:2346
bool IsDungeon() const
Definition: Map.h:427
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibilityDetect
Definition: Object.h:807
void AddOutOfRangeGUID(std::set< uint64 > &guids)
Definition: UpdateData.cpp:31
float m_positionX
Definition: Position.h:50
void AddObjectToRemoveList(WorldObject *obj)
Definition: Map.cpp:2035
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:37
bool IsWithinLOS(float x, float y, float z) const
Definition: Object.cpp:1266
bool IsWorldObject() const
Definition: Object.cpp:1111
void SetNoCreate()
Definition: Cell.h:76
void RemoveWorldObject(WorldObject *obj)
Definition: Map.h:483
bool IsGameMaster() const
Definition: Player.h:1010
virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float pModifyDist)=0
void SetRespawnTime(int32 respawn)
Definition: GameObject.h:710
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealthDetect
Definition: Object.h:804
uint32 GetGUIDLow() const
Definition: Object.h:178
void MonsterYell(const char *text, uint32 language, uint64 TargetGuid)
Definition: Object.cpp:1520
float GetWaterOrGroundLevel(float x, float y, float z, float *ground=NULL, bool swim=false) const
Definition: Map.cpp:1573
void RemoveFromActive(T *obj)
Definition: Map.h:511
DynamicObject * ToDynObject()
Definition: Object.h:383
void SetStatInt32Value(uint16 index, int32 value)
Definition: Object.cpp:936
static uint32 GetAreaId(uint16 areaflag, uint32 map_id)
Definition: Map.cpp:1822
UpdateDataMapType & i_updateDatas
Definition: Object.cpp:2659
#define SIGHT_RANGE_UNIT
Definition: Object.h:39
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:983
TempSummonType GetTempSummonType() const
uint32 modelid1
Definition: Creature.h:134
bool AIM_Initialize(CreatureAI *ai=NULL)
Definition: Creature.cpp:741
iterator begin()
Definition: MapRefManager.h:48
void apply(T *val)
Definition: ByteConverter.h:41
float GetTransOffsetX() const
Definition: Player.h:2400
uint16 m_objectType
Definition: Object.h:400
void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:967
bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const
Definition: Object.cpp:1367
#define sObjectMgr
Definition: ObjectMgr.h:1317
void SendPacket(WorldPacket const *packet)
GameObject * ToGameObject()
Definition: Object.h:377
CharmInfo * GetCharmInfo()
Definition: Unit.h:1458
void setPowerType(Powers power)
Definition: Unit.cpp:7179
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition: Object.h:765
void VisitNearbyGridObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:885
uint32 m_InstanceId
Definition: Object.h:916
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const
Definition: Object.cpp:735
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:884
InvisibilityType
Player * ToPlayer()
Definition: Object.h:368
void MonsterWhisper(const char *text, uint64 receiver, bool IsBossWhisper=false)
Definition: Object.cpp:1534
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:1027
uint32 flags_extra
Definition: Creature.h:195
virtual void RemoveFromWorld()
Definition: Object.h:166
Definition: Totem.h:31
bool ShouldRevealHealthTo(Player *player) const
Definition: Unit.cpp:11001
virtual uint8 getLevelForTarget(WorldObject const *) const
Definition: Object.h:768
virtual bool IsInvisibleDueToDespawn() const
Definition: Object.h:794
uint8 m_objectTypeId
Definition: Object.h:402
uint32 GetId(void) const
Definition: Map.h:333
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition: Object.h:746
uint64 GetGUID() const
Definition: Object.h:177
despawns when the creature disappears
#define IS_PLAYER_GUID(Guid)
Definition: ObjectGuid.h:69
float GetCombatReach() const
Definition: Unit.h:978
bool IsInRange2d(float x, float y, float minRange, float maxRange) const
Definition: Object.cpp:1347
despawns after a specified time
uint8 * GetMask()
Definition: UpdateMask.h:66
uint8 GetTypeId() const
Definition: Object.h:192
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:364
uint32 m_mapId
Definition: Object.h:572
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
Definition: Object.cpp:125
Definition: Pet.h:27
float GetPositionZTarget(Position &pos, float destx, float desty)
Definition: Object.cpp:2436
Position GetHitSpherePointFor(Position const &dest) const
Definition: Object.cpp:1282
bool InitStatsForLevel(uint32 level)
Definition: Pet.cpp:967
CinematicMgr * GetCinematicMgr() const
Definition: Player.h:1258
virtual void DestroyForPlayer(Player *target, bool onDeath=false) const
Definition: Object.cpp:241
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1097
float GetOrientation() const
Definition: Position.h:100
#define UI64FMTD
Definition: Common.h:149
void AddObjectToSwitchList(WorldObject *obj, bool on)
Definition: Map.cpp:2045
void Relocate(float x, float y)
Definition: Position.h:65
virtual bool IsAlwaysVisibleFor(WorldObject const *) const
Definition: Object.h:793
float m_visibilityDistanceOverride
Definition: Object.h:898
Position GetNearPosition(float dist, float angle)
Definition: Object.cpp:2412
PackedGuid m_PackGUID
Definition: Object.h:421
const bool & IsInWorld() const
Definition: Object.h:150
void BuildUpdate(UpdateDataMapType &) override
Definition: Object.cpp:2716
void ApplyModSignedFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:960
uint32 GuidHigh2TypeId(uint32 guid_hi)
Definition: Object.cpp:43
HighGuid
Definition: ObjectGuid.h:51
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition: DBCStructure.h:314
double rand_norm()
Definition: Util.cpp:48
float GetTransOffsetO() const
Definition: Player.h:2412
ZoneScript * m_zoneScript
Definition: Object.h:897
void AddObjectToRemoveList()
Definition: Object.cpp:2017
void BuildPacket(Player *plr)
Definition: Object.cpp:2703
uint32 GetPhaseMask() const
Definition: Object.h:670
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data=0) const
Definition: Map.cpp:1728
uint32 * m_uint32Values_mirror
Definition: Object.h:412
Map * FindMap() const
Definition: Object.h:818
bool RemoveUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:836
TempSummon * SummonCreature(uint32 entry, const Position &pos, SummonPropertiesEntry const *properties=NULL, uint32 duration=0, Unit *summoner=NULL, uint32 spellId=0, TempSummonType spwType=TEMPSUMMON_MANUAL_DESPAWN)
Definition: Object.cpp:2031
void AddUpdateObject(Object *obj)
float GetPositionY() const
Definition: Position.h:98
uint8 m_updateFlag
Definition: Object.h:403
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:876
virtual bool isValid() const
Definition: Object.cpp:1546
void SetSpawnedByDefault(bool b)
Definition: GameObject.h:726
#define MAKE_NEW_GUID(l, e, h)
Definition: ObjectGuid.h:80
Position GetRandomNearPosition(float radius)
Definition: Object.cpp:2426
void SetUInt16Value(uint16 index, uint8 offset, uint16 value)
Definition: Object.cpp:902
void GetPosition(float &x, float &y) const
Definition: Position.h:102
float level
Definition: Map.h:151
bool m_isActive
Definition: Object.h:895
virtual void RemoveFromWorld() override
Definition: Object.cpp:1192
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition: Object.h:810
Position(float x=0, float y=0, float z=0, float o=0)
Definition: Position.h:27
static Player * FindPlayer(uint64, bool force=false)
etc mysql my cnf *Then change max_allowed_packet to a bigger value
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:1052
float GetPositionZ() const
Definition: Position.h:99
void ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:974
bool isActiveObject() const
Definition: Object.h:875
bool CanDetect(WorldObject const *obj, bool ignoreStealth, bool checkAlert=false) const
Definition: Object.cpp:1695
float GetTransOffsetY() const
Definition: Player.h:2404
float GetAngle(Position const *pos) const
TempSummonType
bool PrintIndexError(uint32 index, bool set) const
Definition: Object.cpp:1077
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d)
Definition: Object.cpp:2662
void SendDirectMessage(WorldPacket *data)
Definition: Player.cpp:5717
static uint32 GetZoneId(uint16 areaflag, uint32 map_id)
Definition: Map.cpp:1832
VisibilityDistanceType
Definition: Object.h:119
PackedGuid const & GetPackGUID() const
Definition: Object.h:181
#define DEBUG_LOG(...)
Definition: Log.h:194
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, float x, float y, float z, float ang, const CreatureData *data=NULL)
Definition: Creature.cpp:759
virtual bool CanAlwaysSee(WorldObject const *) const
Definition: Object.h:923
void operator()(WorldPacket &data, int32 loc_idx)
Definition: Object.cpp:1847
float GetAttackDistance(Unit const *pl) const
Definition: Creature.cpp:1532
uint32 GetMapId() const
Definition: Object.h:567
float m_positionZ
Definition: Position.h:52
void SetDuration(int32 dur)
Definition: Pet.h:214
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true)
Definition: Object.cpp:2319
Position GetPosition() const
Definition: Position.h:117
bool IsInMap(const WorldObject *obj) const
Definition: Object.h:721
uint32 GetAreaId() const
Definition: Object.cpp:1207
StealthType
UNORDERED_MAP< Player *, UpdateData > UpdateDataMapType
Definition: Object.h:141
iterator end()
Definition: Map.h:266
bool IsOnCinematic() const
Definition: CinematicMgr.h:39
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2) const
Definition: Map.cpp:1802
float GetVisibilityRange() const
Definition: Map.h:291
void SetUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:796
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:167
void MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
Definition: Object.cpp:1892
void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const
Definition: Object.cpp:2372
Object()
Definition: Object.cpp:68
virtual void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition: Object.cpp:148
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition: Object.cpp:2525
virtual ~Object()
Definition: Object.cpp:95
void InitPetCreateSpells()
Definition: Pet.cpp:1606
#define MAX_VISIBILITY_DISTANCE
Definition: Object.h:38
const char * GetName() const
Definition: Object.h:680
void ApplyPercentModFloatVar(float &var, float val, bool apply)
Definition: Util.h:88
~WorldObject() override
Definition: Object.cpp:81
void ForceValuesUpdateAtIndex(uint32)
Definition: Object.cpp:1827
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:1004
ACE_UINT64 uint64
Definition: Define.h:70
PlayerList const & GetPlayers() const
Definition: Map.h:491
Definition: Cell.h:46
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1805
void Visit(CreatureMapType &m)
Definition: Object.cpp:2677
bool IsInRange(WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
Definition: Object.cpp:1322
uint64 GetPetGUID() const
Definition: Unit.h:1378
bool CanDetectStealthOf(WorldObject const *obj, bool checkAlert=false) const
Definition: Object.cpp:1747
#define VISIBILITY_DISTANCE_GIGANTIC
Definition: Object.h:40
bool isAllowedToLoot(const Creature *creature)
Definition: Player.cpp:15041
#define MAX_PLAYER_STEALTH_DETECT_RANGE
Definition: Unit.h:904
Definition: Unit.h:485
void BuildHeartBeatMsg(WorldPacket *data) const
Definition: Object.cpp:1953
void append(const std::string &str)
Definition: ByteBuffer.h:358
void Set(uint64 const &guid)
Definition: ObjectGuid.h:302
bool HaveAtClient(WorldObject const *u) const
Definition: Player.cpp:18689
bool HasInArc(float arcangle, const Position *pos) const
Definition: Object.cpp:1416
WorldObject(bool isWorldObject)
Definition: Object.cpp:1085
CreatureInfo const * GetCreatureTemplate() const
Definition: Creature.h:565
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1410
void AddUpdateBlock(const ByteBuffer &block)
Definition: UpdateData.cpp:41
#define VISIBILITY_DISTANCE_SMALL
Definition: Object.h:43
virtual void InitSummon()
Map const * GetBaseMap() const
Definition: Object.cpp:2011
#define MAP_ALL_LIQUIDS
Definition: Map.h:142
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=NULL)
Definition: Object.cpp:2305
static void WriteCreate(const MoveSpline &mov, ByteBuffer &data)
void SendObjectDeSpawnAnim(uint64 guid)
Definition: Object.cpp:1966
uint32 GetLength()
Definition: UpdateMask.h:58
int GetSessionDbLocaleIndex() const
Definition: WorldSession.h:237
void BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const *text, uint32 language, char const *name, uint64 TargetGuid) const
Definition: Object.cpp:1934
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const
Definition: Object.cpp:747
bool LoadPetFromDB(Player *owner, uint32 petentry=0, uint32 petnumber=0, bool current=false)
Definition: Pet.cpp:131
Creature * ToCreature()
Definition: Object.h:371
virtual void UpdateObjectVisibility(bool forced=true)
Definition: Object.cpp:2650
void SetZoneScript()
Definition: Object.cpp:2129
float m_SightDistance
Definition: Creature.h:797
void SetFaction(uint32 faction)
Definition: Unit.h:1117
void AddToActive(T *obj)
Definition: Map.h:502
float * m_floatValues
Definition: Object.h:409
Creature * SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI *(*GetAI)(Creature *)=NULL)
Definition: Object.cpp:2280
uint32 GetGUIDHigh() const
Definition: Object.h:180
void SetWorldObject(bool apply)
Definition: Object.cpp:1103
void SetFloatValue(uint16 index, float value)
Definition: Object.cpp:857
float GetExactDist(float x, float y, float z) const
Definition: Position.h:150
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition: Object.cpp:1421
void SetCount(uint32 valuesCount)
Definition: UpdateMask.h:71
uint32 m_phaseMask
Definition: Object.h:917
uint16 m_valuesCount
Definition: Object.h:414
bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 ArtKit=0)
Definition: GameObject.cpp:166
iterator begin()
virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
Definition: Object.cpp:1960
uint32 GetFallTime() const
Definition: Object.h:515
uint32 GetTeam() const
Definition: Player.h:2066
void SetPower(Powers power, uint32 val)
Definition: Unit.cpp:11032
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealth
Definition: Object.h:803
static IVMapManager * createOrGetVMapManager()
bool isTappedBy(Player const *player) const
Definition: Creature.cpp:1033
#define VISIBILITY_DISTANCE_TINY
Definition: Object.h:44
#define ASSERT
Definition: Errors.h:29
GameObject * FindNearestGameObject(uint32 entry, float range)
Definition: Object.cpp:2328
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibility
Definition: Object.h:806
uint32 GetTransTime() const
Definition: Player.h:2416
bool AddUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:815
void SetTempSummonType(TempSummonType type)
void PlayDistanceSound(uint32 sound_id, Player *target=NULL)
Definition: Object.cpp:2595
T_VALUES GetValue(FLAG_TYPE flag) const
Definition: Object.h:601
void DestroyForNearbyPlayers()
Definition: Object.cpp:2616
#define INVALID_HEIGHT
Definition: Map.h:259
void SetLevel(uint32 lvl)
Definition: Unit.cpp:10931
const int32 & GetInt32Value(uint16 index) const
Definition: Object.h:204
virtual void InitStats(uint32 lifetime)
WorldObject const & i_object
Definition: Object.cpp:1856
uint32 GetEntry() const
Definition: Object.h:186
bool IsPositionValid() const
Definition: Position.cpp:40
WorldSession * GetSession() const
Definition: Player.h:1947
#define sWorld
Definition: World.h:860
void SetVisibilityDistanceOverride(VisibilityDistanceType type)
Definition: Object.cpp:1155
#define CONTACT_DISTANCE
Definition: Object.h:34
void SetHealth(uint32 val)
Definition: Unit.cpp:10940
void Visit(GridRefManager< SKIP > &)
Definition: Object.cpp:2713
void SetCreatorGUID(uint64 creator)
Definition: Unit.h:1350
void AddWorldObject(WorldObject *obj)
Definition: Map.h:479
ACE_UINT16 uint16
Definition: Define.h:72
float GetDistanceZ(const WorldObject *obj) const
Definition: Object.cpp:1218
void _InitValues()
Definition: Object.cpp:114
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:7222
bool CanSeeOrDetect(WorldObject const *obj, bool ignoreStealth=false, bool distanceCheck=false, bool checkAlert=false) const
Definition: Object.cpp:1612
virtual bool IsAlwaysDetectableFor(WorldObject const *) const
Definition: Object.h:796
ACE_UINT32 uint32
Definition: Define.h:71
Definition: Pet.h:29
float GetPositionX() const
Definition: Position.h:97
#define MAX_HEIGHT
Definition: Map.h:258
uint32 GetCount()
Definition: UpdateMask.h:62
bool InSamePhase(uint32 phasemask) const
Definition: Object.h:671
void SetBit(uint32 index)
Definition: UpdateMask.h:39
bool getObjectHitPos(float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition: Map.cpp:1808
Definition: Unit.h:908
float m_CombatDistance
Definition: Creature.h:797
void BuildOutOfRangeUpdateBlock(UpdateData *data) const
Definition: Object.cpp:236
float GetObjectSize() const
Definition: Object.h:645
Map const * GetParent() const
Definition: Map.h:344
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
Definition: Pet.cpp:1770
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const
Definition: Object.cpp:2381
Definition: Player.h:923
bool CanDetectInvisibilityOf(WorldObject const *obj) const
Definition: Object.cpp:1716
uint32 GetInstanceId() const
Definition: Map.h:390
void Visit(PlayerMapType &m)
Definition: Object.cpp:2663
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition: CellImpl.h:121
void SendUpdateToPlayer(Player *player)
Definition: Object.cpp:207
bool IsInSameGroupWith(Player const *p) const
Definition: Player.cpp:2319
Unit * ToUnit()
Definition: Object.h:374
uint32 GetBlockCount()
Definition: UpdateMask.h:54
float GetSightRange(const WorldObject *target=NULL) const
Definition: Object.cpp:1585
void VisitNearbyWorldObject(const float &radius, NOTIFIER &notifier) const
Definition: Object.h:883
iterator end()
Definition: MapRefManager.h:52
Definition: Pet.h:146
MonsterChatBuilder(WorldObject const &obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID)
Definition: Object.cpp:1845
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1506
#define atol(a)
Definition: Common.h:162
float GetHealthPct() const
Definition: Unit.h:1085
InstanceData * GetInstanceData()
Definition: Object.cpp:1212
const float & GetFloatValue(uint16 index) const
Definition: Object.h:222
void NormalizeMapCoord(float &c)
Definition: GridDefines.h:184