OregonCore  revision fb2a440-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 <http://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  Creature const* creature = ToCreature();
536 
537  if (creature)
538  {
539  if (!creature->isDead())
540  {
541  //sLog.outError("MOB ALIVE!");
542  if (creature->isTappedBy(target))
543  *data << (m_uint32Values[index] & ~UNIT_DYNFLAG_OTHER_TAGGER);
544  else
545  *data << (m_uint32Values[index] | UNIT_DYNFLAG_OTHER_TAGGER);
546  }
547  else
548  {
549  //sLog.outError("MOB DEAD!");
550  if (!target->isAllowedToLoot(creature))
551  *data << (m_uint32Values[index] & ~UNIT_DYNFLAG_LOOTABLE);
552  else
553  *data << (m_uint32Values[index] | UNIT_DYNFLAG_LOOTABLE);
554  }
555  }
556 
557  }
558 
559  // hide RAF menu to non-RAF linked friends
560  else if (index == UNIT_DYNAMIC_FLAGS && GetTypeId() == TYPEID_PLAYER)
561  {
562  if (sObjectMgr.GetRAFLinkStatus(target->ToPlayer(), this->ToPlayer()) != RAF_LINK_NONE)
563  *data << (m_uint32Values[ index ]);
564  else
565  *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_REFER_A_FRIEND);
566  }
567  // FG: pretend that OTHER players in own group are friendly ("blue")
568  else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
569  {
570  bool ch = false;
571  if (target->GetTypeId() == TYPEID_PLAYER && GetTypeId() == TYPEID_PLAYER && target != this)
572  {
573  if (target->IsInSameGroupWith(ToPlayer()) || target->IsInSameRaidWith(ToPlayer()))
574  {
575  if (index == UNIT_FIELD_BYTES_2)
576  {
577  DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (flag)", target->GetName(), ToPlayer()->GetName());
578  *data << (m_uint32Values[ index ] & ((UNIT_BYTE2_FLAG_SANCTUARY | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5) << 8)); // this flag is at uint8 offset 1 !!
579 
580  ch = true;
581  }
582  else if (index == UNIT_FIELD_FACTIONTEMPLATE)
583  {
584  FactionTemplateEntry const* ft1, *ft2;
586  ft2 = target->ToPlayer()->GetFactionTemplateEntry();
587  if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
588  {
589  uint32 faction = target->ToPlayer()->GetFaction(); // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
590  DEBUG_LOG("-- VALUES_UPDATE: Sending '%s' the blue-group-fix from '%s' (faction %u)", target->GetName(), ToPlayer()->GetName(), faction);
591  *data << uint32(faction);
592  ch = true;
593  }
594  }
595  }
596  }
597  if (!ch)
598  *data << m_uint32Values[ index ];
599  }
600  else if (index == UNIT_FIELD_HEALTH)
601  {
602  if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER)
603  {
604  const Unit* me = reinterpret_cast<const Unit*>(this);
605  if (me->ShouldRevealHealthTo(target))
606  *data << m_uint32Values[ index ];
607  else
608  *data << uint32(std::ceil(me->GetHealthPct()));
609  }
610  else
611  *data << m_uint32Values[ index ];
612  }
613  else if (index == UNIT_FIELD_MAXHEALTH)
614  {
615  if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER)
616  {
617  const Unit* me = reinterpret_cast<const Unit*>(this);
618  if (me->ShouldRevealHealthTo(target))
619  *data << m_uint32Values[ index ];
620  else
621  *data << uint32(100);
622  }
623  else
624  *data << m_uint32Values[ index ];
625  }
626  else
627  {
628  // send in current format (float as float, uint32 as uint32)
629  *data << m_uint32Values[ index ];
630  }
631  }
632  }
633  }
634  else if (isType(TYPEMASK_GAMEOBJECT)) // gameobject case
635  {
636  for (uint16 index = 0; index < m_valuesCount; ++index)
637  {
638  if (updateMask->GetBit(index))
639  {
640  // send in current format (float as float, uint32 as uint32)
641  if (index == GAMEOBJECT_DYN_FLAGS)
642  {
643  if (IsActivateToQuest)
644  {
645  switch (((GameObject*)this)->GetGoType())
646  {
650  *data << uint16(-1);
651  break;
652  default:
653  *data << uint32(0); // unknown, not happen.
654  break;
655  }
656  }
657  else
658  *data << uint32(0); // disable quest object
659  }
660  else
661  *data << m_uint32Values[ index ]; // other cases
662  }
663  }
664  }
665  else // other objects case (no special index checks)
666  {
667  for (uint16 index = 0; index < m_valuesCount; ++index)
668  {
669  if (updateMask->GetBit(index))
670  {
671  // send in current format (float as float, uint32 as uint32)
672  *data << m_uint32Values[ index ];
673  }
674  }
675  }
676 }
677 
678 void Object::ClearUpdateMask(bool remove)
679 {
681 
682  if (m_objectUpdated)
683  {
684  if (remove)
686  m_objectUpdated = false;
687  }
688 }
689 
691 {
692  UpdateDataMapType::iterator iter = data_map.find(pl);
693 
694  if (iter == data_map.end())
695  {
696  std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(pl, UpdateData()));
697  ASSERT(p.second);
698  iter = p.first;
699  }
700 
701  BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
702 }
703 
704 bool Object::LoadValues(const char* data)
705 {
706  if (!m_uint32Values) _InitValues();
707 
708  Tokens tokens = StrSplit(data, " ");
709 
710  if (tokens.size() != m_valuesCount)
711  return false;
712 
713  Tokens::iterator iter;
714  int index;
715  for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, ++index)
716  m_uint32Values[index] = atol((*iter).c_str());
717 
718  return true;
719 }
720 
721 void Object::_LoadIntoDataField(const char* data, uint32 startOffset, uint32 count)
722 {
723  if (!data)
724  return;
725 
726  Tokens tokens = StrSplit(data, " ");
727 
728  if (tokens.size() != count)
729  return;
730 
731  Tokens::iterator iter;
732  uint32 index;
733  for (iter = tokens.begin(), index = 0; index < count; ++iter, ++index)
734  m_uint32Values[startOffset + index] = atol((*iter).c_str());
735 }
736 
737 void Object::_SetUpdateBits(UpdateMask* updateMask, Player* /*target*/) const
738 {
740  uint32* mirror = m_uint32Values_mirror;
741 
742  for (uint16 index = 0; index < m_valuesCount; ++index, ++value, ++mirror)
743  {
744  if (*mirror != *value)
745  updateMask->SetBit(index);
746  }
747 }
748 
749 void Object::_SetCreateBits(UpdateMask* updateMask, Player* /*target*/) const
750 {
752 
753  for (uint16 index = 0; index < m_valuesCount; ++index, ++value)
754  {
755  if (*value)
756  updateMask->SetBit(index);
757  }
758 }
759 
761 {
762  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
763 
764  if (m_int32Values[ index ] != value)
765  {
766  m_int32Values[ index ] = value;
767 
768  if (m_inWorld)
769  {
770  if (!m_objectUpdated)
771  {
773  m_objectUpdated = true;
774  }
775  }
776  }
777 }
778 
780 {
781  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
782 
783  if (m_uint32Values[ index ] != value)
784  {
785  m_uint32Values[ index ] = value;
786 
787  if (m_inWorld)
788  {
789  if (!m_objectUpdated)
790  {
792  m_objectUpdated = true;
793  }
794  }
795  }
796 }
797 
799 {
800  ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
801  if (*((uint64*) & (m_uint32Values[ index ])) != value)
802  {
803  m_uint32Values[ index ] = *((uint32*)&value);
804  m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1);
805 
806  if (m_inWorld)
807  {
808  if (!m_objectUpdated)
809  {
811  m_objectUpdated = true;
812  }
813  }
814  }
815 }
816 
818 {
819  ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true));
820  if (value && !*((uint64*) & (m_uint32Values[index])))
821  {
822  m_uint32Values[ index ] = *((uint32*)&value);
823  m_uint32Values[ index + 1 ] = *(((uint32*)&value) + 1);
824 
825  if (m_inWorld)
826  {
827  if (!m_objectUpdated)
828  {
830  m_objectUpdated = true;
831  }
832  }
833  return true;
834  }
835  return false;
836 }
837 
839 {
840  ASSERT(index + 1 < m_valuesCount || PrintIndexError(index , true));
841  if (value && *((uint64*) & (m_uint32Values[index])) == value)
842  {
843  m_uint32Values[ index ] = 0;
844  m_uint32Values[ index + 1 ] = 0;
845 
846  if (m_inWorld)
847  {
848  if (!m_objectUpdated)
849  {
851  m_objectUpdated = true;
852  }
853  }
854  return true;
855  }
856  return false;
857 }
858 
860 {
861  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
862 
863  if (m_floatValues[ index ] != value)
864  {
865  m_floatValues[ index ] = value;
866 
867  if (m_inWorld)
868  {
869  if (!m_objectUpdated)
870  {
872  m_objectUpdated = true;
873  }
874  }
875  }
876 }
877 
879 {
880  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
881 
882  if (offset > 4)
883  {
884  sLog.outError("Object::SetByteValue: wrong offset %u", offset);
885  return;
886  }
887 
888  if (uint8(m_uint32Values[ index ] >> (offset * 8)) != value)
889  {
890  m_uint32Values[ index ] &= ~uint32(uint32(0xFF) << (offset * 8));
891  m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 8));
892 
893  if (m_inWorld)
894  {
895  if (!m_objectUpdated)
896  {
898  m_objectUpdated = true;
899  }
900  }
901  }
902 }
903 
905 {
906  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
907 
908  if (offset > 2)
909  {
910  sLog.outError("Object::SetUInt16Value: wrong offset %u", offset);
911  return;
912  }
913 
914  if (uint16(m_uint32Values[ index ] >> (offset * 16)) != value)
915  {
916  m_uint32Values[ index ] &= ~uint32(uint32(0xFFFF) << (offset * 16));
917  m_uint32Values[ index ] |= uint32(uint32(value) << (offset * 16));
918 
919  if (m_inWorld)
920  {
921  if (!m_objectUpdated)
922  {
924  m_objectUpdated = true;
925  }
926  }
927  }
928 }
929 
931 {
932  if (value < 0)
933  value = 0.0f;
934 
935  SetFloatValue(index, value);
936 }
937 
939 {
940  if (value < 0)
941  value = 0;
942 
943  SetUInt32Value(index, uint32(value));
944 }
945 
947 {
948  int32 cur = GetUInt32Value(index);
949  cur += (apply ? val : -val);
950  if (cur < 0)
951  cur = 0;
952  SetUInt32Value(index, cur);
953 }
954 
956 {
957  int32 cur = GetInt32Value(index);
958  cur += (apply ? val : -val);
959  SetInt32Value(index, cur);
960 }
961 
962 void Object::ApplyModSignedFloatValue(uint16 index, float val, bool apply)
963 {
964  float cur = GetFloatValue(index);
965  cur += (apply ? val : -val);
966  SetFloatValue(index, cur);
967 }
968 
969 void Object::ApplyPercentModFloatValue(uint16 index, float val, bool apply)
970 {
971  float value = GetFloatValue(index);
972  ApplyPercentModFloatVar(value, val, apply);
973  SetFloatValue(index, value);
974 }
975 
976 void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
977 {
978  float cur = GetFloatValue(index);
979  cur += (apply ? val : -val);
980  if (cur < 0)
981  cur = 0;
982  SetFloatValue(index, cur);
983 }
984 
985 void Object::SetFlag(uint16 index, uint32 newFlag)
986 {
987  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
988  uint32 oldval = m_uint32Values[ index ];
989  uint32 newval = oldval | newFlag;
990 
991  if (oldval != newval)
992  {
993  m_uint32Values[ index ] = newval;
994 
995  if (m_inWorld)
996  {
997  if (!m_objectUpdated)
998  {
1000  m_objectUpdated = true;
1001  }
1002  }
1003  }
1004 }
1005 
1006 void Object::RemoveFlag(uint16 index, uint32 oldFlag)
1007 {
1008  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1010 
1011  uint32 oldval = m_uint32Values[ index ];
1012  uint32 newval = oldval & ~oldFlag;
1013 
1014  if (oldval != newval)
1015  {
1016  m_uint32Values[ index ] = newval;
1017 
1018  if (m_inWorld)
1019  {
1020  if (!m_objectUpdated)
1021  {
1023  m_objectUpdated = true;
1024  }
1025  }
1026  }
1027 }
1028 
1029 void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
1030 {
1031  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1032 
1033  if (offset > 4)
1034  {
1035  sLog.outError("Object::SetByteFlag: wrong offset %u", offset);
1036  return;
1037  }
1038 
1039  if (!(uint8(m_uint32Values[ index ] >> (offset * 8)) & newFlag))
1040  {
1041  m_uint32Values[ index ] |= uint32(uint32(newFlag) << (offset * 8));
1042 
1043  if (m_inWorld)
1044  {
1045  if (!m_objectUpdated)
1046  {
1048  m_objectUpdated = true;
1049  }
1050  }
1051  }
1052 }
1053 
1054 void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag)
1055 {
1056  ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1057 
1058  if (offset > 4)
1059  {
1060  sLog.outError("Object::RemoveByteFlag: wrong offset %u", offset);
1061  return;
1062  }
1063 
1064  if (uint8(m_uint32Values[ index ] >> (offset * 8)) & oldFlag)
1065  {
1066  m_uint32Values[ index ] &= ~uint32(uint32(oldFlag) << (offset * 8));
1067 
1068  if (m_inWorld)
1069  {
1070  if (!m_objectUpdated)
1071  {
1073  m_objectUpdated = true;
1074  }
1075  }
1076  }
1077 }
1078 
1079 bool Object::PrintIndexError(uint32 index, bool set) const
1080 {
1081  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);
1082 
1083  // assert must fail after function call
1084  return false;
1085 }
1086 
1087 WorldObject::WorldObject(bool isWorldObject):
1088  WorldLocation()
1089  , m_groupLootTimer(0)
1090  , lootingGroupLeaderGUID(0)
1091  , m_isWorldObject(isWorldObject)
1092  , m_name("")
1093  , m_isActive(false)
1094  , m_zoneScript(NULL)
1095  , m_currMap(NULL)
1096  , m_InstanceId(0)
1097  , m_phaseMask(PHASEMASK_NORMAL)
1098  , m_notifyflags(0), m_executed_notifies(0)
1099 {
1102 }
1103 
1105 {
1106  if (!IsInWorld())
1107  return;
1108 
1109  GetMap()->AddObjectToSwitchList(this, on);
1110 }
1111 
1113 {
1114  if (m_isWorldObject)
1115  return true;
1116 
1117  if (ToCreature() && ToCreature()->m_isTempWorldObject)
1118  return true;
1119 
1120  return false;
1121 }
1122 
1124 {
1125  if (m_isActive == on)
1126  return;
1127 
1128  if (GetTypeId() == TYPEID_PLAYER)
1129  return;
1130 
1131  m_isActive = on;
1132 
1133  if (!IsInWorld())
1134  return;
1135 
1136  Map* map = FindMap();
1137  if (!map)
1138  return;
1139 
1140  if (on)
1141  {
1142  if (GetTypeId() == TYPEID_UNIT)
1143  map->AddToActive(ToCreature());
1144  else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
1145  map->AddToActive((DynamicObject*)this);
1146  }
1147  else
1148  {
1149  if (GetTypeId() == TYPEID_UNIT)
1150  map->RemoveFromActive(ToCreature());
1151  else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
1152  map->RemoveFromActive((DynamicObject*)this);
1153  }
1154 }
1155 
1157 {
1158  if (IsInWorld())
1159  RemoveFromWorld();
1160 }
1161 
1162 void WorldObject::_Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask)
1163 {
1164  Object::_Create(guidlow, 0, guidhigh);
1165 
1166  m_phaseMask = phaseMask;
1167 }
1168 
1170 {
1171  if (!IsInWorld())
1172  return;
1173 
1175 
1177 }
1178 
1180 {
1182 }
1183 
1185 {
1187 }
1188 
1190 {
1191  Map* map = GetMap();
1192  return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;
1193 }
1194 
1196 {
1197  float dz = fabs(GetPositionZ() - obj->GetPositionZ());
1198  float sizefactor = GetObjectSize() + obj->GetObjectSize();
1199  float dist = dz - sizefactor;
1200  return (dist > 0 ? dist : 0);
1201 }
1202 
1203 float WorldObject::GetDistanceSqr(float x, float y, float z) const
1204 {
1205  float dx = GetPositionX() - x;
1206  float dy = GetPositionY() - y;
1207  float dz = GetPositionZ() - z;
1208  float sizefactor = GetObjectSize();
1209  float dist = dx * dx + dy * dy + dz * dz - sizefactor;
1210  return (dist > 0 ? dist : 0);
1211 }
1212 
1213 bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
1214 {
1215  float dx = GetPositionX() - obj->GetPositionX();
1216  float dy = GetPositionY() - obj->GetPositionY();
1217  float distsq = dx * dx + dy * dy;
1218  if (is3D)
1219  {
1220  float dz = GetPositionZ() - obj->GetPositionZ();
1221  distsq += dz * dz;
1222  }
1223  float sizefactor = GetObjectSize() + obj->GetObjectSize();
1224  float maxdist = dist2compare + sizefactor;
1225 
1226  return distsq < maxdist * maxdist;
1227 }
1228 
1230 {
1231  if (!IsInMap(obj))
1232  return false;
1233 
1234  float x, y, z;
1235  if (obj->GetTypeId() == TYPEID_PLAYER)
1236  obj->GetPosition(x, y, z);
1237  else
1238  obj->GetHitSpherePointFor(GetPosition(), x, y, z);
1239 
1240  return IsWithinLOS(x, y, z);
1241 }
1242 
1243 bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
1244 {
1245  if (IsInWorld())
1246  {
1247  float x, y, z;
1248  if (GetTypeId() == TYPEID_PLAYER)
1249  GetPosition(x, y, z);
1250  else
1251  GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
1252 
1253  return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f);
1254  }
1255 
1256  return true;
1257 }
1258 
1260 {
1261  G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
1262  G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
1263  G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * GetObjectSize();
1264 
1265  return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
1266 }
1267 
1268 void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const
1269 {
1270  Position pos = GetHitSpherePointFor(dest);
1271  x = pos.GetPositionX();
1272  y = pos.GetPositionY();
1273  z = pos.GetPositionZ();
1274 }
1275 
1276 bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const
1277 {
1278  float dx1 = GetPositionX() - obj1->GetPositionX();
1279  float dy1 = GetPositionY() - obj1->GetPositionY();
1280  float distsq1 = dx1 * dx1 + dy1 * dy1;
1281  if (is3D)
1282  {
1283  float dz1 = GetPositionZ() - obj1->GetPositionZ();
1284  distsq1 += dz1 * dz1;
1285  }
1286 
1287  float dx2 = GetPositionX() - obj2->GetPositionX();
1288  float dy2 = GetPositionY() - obj2->GetPositionY();
1289  float distsq2 = dx2 * dx2 + dy2 * dy2;
1290  if (is3D)
1291  {
1292  float dz2 = GetPositionZ() - obj2->GetPositionZ();
1293  distsq2 += dz2 * dz2;
1294  }
1295 
1296  return distsq1 < distsq2;
1297 }
1298 
1299 bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D /* = true */) const
1300 {
1301  float dx = GetPositionX() - obj->GetPositionX();
1302  float dy = GetPositionY() - obj->GetPositionY();
1303  float distsq = dx * dx + dy * dy;
1304  if (is3D)
1305  {
1306  float dz = GetPositionZ() - obj->GetPositionZ();
1307  distsq += dz * dz;
1308  }
1309 
1310  float sizefactor = GetObjectSize() + obj->GetObjectSize();
1311 
1312  // check only for real range
1313  if (minRange > 0.0f)
1314  {
1315  float mindist = minRange + sizefactor;
1316  if (distsq < mindist * mindist)
1317  return false;
1318  }
1319 
1320  float maxdist = maxRange + sizefactor;
1321  return distsq < maxdist * maxdist;
1322 }
1323 
1324 bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) const
1325 {
1326  float dx = GetPositionX() - x;
1327  float dy = GetPositionY() - y;
1328  float distsq = dx * dx + dy * dy;
1329 
1330  float sizefactor = GetObjectSize();
1331 
1332  // check only for real range
1333  if (minRange > 0.0f)
1334  {
1335  float mindist = minRange + sizefactor;
1336  if (distsq < mindist * mindist)
1337  return false;
1338  }
1339 
1340  float maxdist = maxRange + sizefactor;
1341  return distsq < maxdist * maxdist;
1342 }
1343 
1344 bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float maxRange) const
1345 {
1346  float dx = GetPositionX() - x;
1347  float dy = GetPositionY() - y;
1348  float dz = GetPositionZ() - z;
1349  float distsq = dx * dx + dy * dy + dz * dz;
1350 
1351  float sizefactor = GetObjectSize();
1352 
1353  // check only for real range
1354  if (minRange > 0.0f)
1355  {
1356  float mindist = minRange + sizefactor;
1357  if (distsq < mindist * mindist)
1358  return false;
1359  }
1360 
1361  float maxdist = maxRange + sizefactor;
1362  return distsq < maxdist * maxdist;
1363 }
1364 
1365 bool WorldObject::HasInArc(const float arcangle, const float x, const float y) const
1366 {
1367  // always have self in arc
1368  if (x == m_positionX && y == m_positionY)
1369  return true;
1370 
1371  float arc = arcangle;
1372 
1373  // move arc to range 0.. 2*pi
1374  while ( arc >= 2.0f * float(M_PI) )
1375  arc -= 2.0f * float(M_PI);
1376  while ( arc < 0 )
1377  arc += 2.0f * float(M_PI);
1378 
1379  float angle = GetAngle( x, y );
1380  angle -= GetOrientation();
1381 
1382  // move angle to range -pi ... +pi
1383  while ( angle > float(M_PI))
1384  angle -= 2.0f * float(M_PI);
1385  while (angle < -M_PI)
1386  angle += 2.0f * float(M_PI);
1387 
1388  float lborder = -1 * (arc / 2.0f); // in range -pi..0
1389  float rborder = (arc / 2.0f); // in range 0..pi
1390  return (( angle >= lborder ) && ( angle <= rborder ));
1391 }
1392 
1393 bool WorldObject::HasInArc(float arc, const Position* obj) const
1394 {
1395  return this->HasInArc(arc, obj->GetPositionX(), obj->GetPositionY());
1396 }
1397 
1398 void WorldObject::GetRandomPoint(const Position& pos, float distance, float& rand_x, float& rand_y, float& rand_z) const
1399 {
1400  if (!distance)
1401  {
1402  pos.GetPosition(rand_x, rand_y, rand_z);
1403  return;
1404  }
1405 
1406  // angle to face `obj` to `this`
1407  float angle = rand_norm() * 2 * M_PI;
1408  float new_dist = rand_norm() * distance;
1409 
1410  rand_x = pos.m_positionX + new_dist * cos(angle);
1411  rand_y = pos.m_positionY + new_dist * sin(angle);
1412  rand_z = pos.m_positionZ;
1413 
1414  Oregon::NormalizeMapCoord(rand_x);
1415  Oregon::NormalizeMapCoord(rand_y);
1416  UpdateGroundPositionZ(rand_x, rand_y, rand_z); // update to LOS height if available
1417 }
1418 
1419 void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
1420 {
1421  switch (GetTypeId())
1422  {
1423  case TYPEID_UNIT:
1424  {
1425  // non fly unit don't must be in air
1426  // non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
1427  if (!((Creature const*)this)->CanFly())
1428  {
1429  bool canSwim = ((Creature const*)this)->CanSwim();
1430  float ground_z = z;
1431  float max_z = canSwim
1432  ? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
1433  : ((ground_z = GetBaseMap()->GetHeight(x, y, z, true)));
1434  if (max_z > INVALID_HEIGHT)
1435  {
1436  if (z > max_z)
1437  z = max_z;
1438  else if (z < ground_z)
1439  z = ground_z;
1440  }
1441  }
1442  else
1443  {
1444  float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
1445  if (z < ground_z)
1446  z = ground_z;
1447  }
1448  break;
1449  }
1450  case TYPEID_PLAYER:
1451  {
1452  // for server controlled moves playr work same as creature (but it can always swim)
1453  if (!((Player const*)this)->CanFly())
1454  {
1455  float ground_z = z;
1456  float max_z = GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
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  default:
1474  {
1475  float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
1476  if (ground_z > INVALID_HEIGHT)
1477  z = ground_z;
1478  break;
1479  }
1480  }
1481 }
1482 
1483 void WorldObject::UpdateGroundPositionZ(float x, float y, float& z) const
1484 {
1485  float new_z = GetBaseMap()->GetHeight(x, y, z, true);
1486  if (new_z > INVALID_HEIGHT)
1487  z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
1488 }
1489 
1490 void WorldObject::MonsterSay(const char* text, uint32 language, uint64 TargetGuid)
1491 {
1492  WorldPacket data(SMSG_MESSAGECHAT, 200);
1493  BuildMonsterChat(&data, CHAT_MSG_MONSTER_SAY, text, language, GetName(), TargetGuid);
1494  SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY), true);
1495 }
1496 
1497 void WorldObject::MonsterYell(const char* text, uint32 language, uint64 TargetGuid)
1498 {
1499  WorldPacket data(SMSG_MESSAGECHAT, 200);
1500  BuildMonsterChat(&data, CHAT_MSG_MONSTER_YELL, text, language, GetName(), TargetGuid);
1501  SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL), true);
1502 }
1503 
1504 void WorldObject::MonsterTextEmote(const char* text, uint64 TargetGuid, bool IsBossEmote)
1505 {
1506  WorldPacket data(SMSG_MESSAGECHAT, 200);
1507  BuildMonsterChat(&data, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, text, LANG_UNIVERSAL, GetName(), TargetGuid);
1509 }
1510 
1511 void WorldObject::MonsterWhisper(const char* text, uint64 receiver, bool IsBossWhisper)
1512 {
1513  Player* player = sObjectMgr.GetPlayer(receiver);
1514  if (!player || !player->GetSession())
1515  return;
1516 
1517  WorldPacket data(SMSG_MESSAGECHAT, 200);
1518  BuildMonsterChat(&data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, GetName(), receiver);
1519 
1520  player->GetSession()->SendPacket(&data);
1521 }
1522 
1524 {
1525  if (!IsInWorld())
1526  return false;
1527 
1528  return true;
1529 }
1530 
1532 {
1533  if (ToPlayer())
1534  {
1535  if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
1537  return GetMap()->GetVisibilityRange();
1538  }
1539  else if (ToCreature())
1540  return ToCreature()->m_SightDistance;
1541  else if (ToDynObject())
1542  {
1543  if (isActiveObject())
1544  return GetMap()->GetVisibilityRange();
1545  else
1546  return 0.0f;
1547  }
1548  else
1549  return 0.0f;
1550 }
1551 
1553 {
1554  if (isActiveObject() && !ToPlayer())
1555  return MAX_VISIBILITY_DISTANCE;
1556  else
1557  return GetMap()->GetVisibilityRange();
1558 }
1559 
1560 float WorldObject::GetSightRange(const WorldObject* target) const
1561 {
1562  if (ToUnit())
1563  {
1564  if (ToPlayer())
1565  {
1566  if (target && target->isActiveObject() && !target->ToPlayer())
1567  return MAX_VISIBILITY_DISTANCE;
1568  else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
1570  else
1571  return GetMap()->GetVisibilityRange();
1572  }
1573  else if (ToCreature())
1574  return ToCreature()->m_SightDistance;
1575  else
1576  return SIGHT_RANGE_UNIT;
1577  }
1578 
1579  if (ToDynObject() && isActiveObject())
1580  return GetMap()->GetVisibilityRange();
1581 
1582  return 0.0f;
1583 }
1584 
1585 bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck, bool checkAlert) const
1586 {
1587  if (this == obj)
1588  return true;
1589 
1590  if (obj->IsNeverVisible() || CanNeverSee(obj))
1591  return false;
1592 
1593  if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj))
1594  return true;
1595 
1596  bool corpseVisibility = false;
1597  if (distanceCheck)
1598  {
1599  bool corpseCheck = false;
1600  if (const Player* thisPlayer = ToPlayer())
1601  {
1602  if (thisPlayer->isDead() && thisPlayer->GetHealth() > 0 && // Cheap way to check for ghost state
1604  {
1605  if (Corpse* corpse = thisPlayer->GetCorpse())
1606  {
1607  corpseCheck = true;
1608  if (corpse->IsWithinDist(thisPlayer, GetSightRange(obj), false))
1609  if (corpse->IsWithinDist(obj, GetSightRange(obj), false))
1610  corpseVisibility = true;
1611  }
1612  }
1613  }
1614 
1615  WorldObject const* viewpoint = this;
1616  if (Player const* player = this->ToPlayer())
1617  viewpoint = player->GetViewpoint();
1618 
1619  if (!viewpoint)
1620  viewpoint = this;
1621 
1622  if (!corpseCheck && !viewpoint->IsWithinDist(obj, GetSightRange(obj), false))
1623  return false;
1624  }
1625 
1626  // GM visibility off or hidden NPC
1628  {
1629  // Stop checking other things for GMs
1631  return true;
1632  }
1633  else
1635 
1636  // Ghost players, Spirit Healers, and some other NPCs
1638  {
1639  // Alive players can see dead players in some cases, but other objects can't do that
1640  if (const Player* thisPlayer = ToPlayer())
1641  {
1642  if (const Player* objPlayer = obj->ToPlayer())
1643  {
1644  if (thisPlayer->GetTeam() != objPlayer->GetTeam() || !thisPlayer->IsGroupVisibleFor(objPlayer))
1645  return false;
1646  }
1647  else
1648  return false;
1649  }
1650  else
1651  return false;
1652  }
1653 
1654  if (obj->IsInvisibleDueToDespawn())
1655  return false;
1656 
1657  if (!CanDetect(obj, ignoreStealth, checkAlert))
1658  return false;
1659 
1660  return true;
1661 }
1662 
1664 {
1665  return GetMap() != obj->GetMap() || !InSamePhase(obj);
1666 }
1667 
1668 bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert) const
1669 {
1670  const WorldObject* seer = this;
1671 
1672  // Pets don't have detection, they use the detection of their masters
1673  if (const Unit* thisUnit = ToUnit())
1674  if (Unit* controller = thisUnit->GetCharmerOrOwner())
1675  seer = controller;
1676 
1677  if (obj->IsAlwaysDetectableFor(seer))
1678  return true;
1679 
1680  if (!ignoreStealth && !seer->CanDetectInvisibilityOf(obj))
1681  return false;
1682 
1683  if (!ignoreStealth && !seer->CanDetectStealthOf(obj, checkAlert))
1684  return false;
1685 
1686  return true;
1687 }
1688 
1690 {
1692 
1693  // Check for not detected types
1694  if (mask != obj->m_invisibility.GetFlags())
1695  return false;
1696 
1697  // It isn't possible in invisibility to detect something that can't detect the invisible object
1698  // (it's at least true for spell: 66)
1699  // It seems like that only Units are affected by this check (couldn't see arena doors with preparation invisibility)
1700  if (obj->ToUnit())
1702  return false;
1703 
1704  for (uint32 i = 0; i < TOTAL_INVISIBILITY_TYPES; ++i)
1705  {
1706  if (!(mask & (1 << i)))
1707  continue;
1708 
1709  int32 objInvisibilityValue = obj->m_invisibility.GetValue(InvisibilityType(i));
1710  int32 ownInvisibilityDetectValue = m_invisibilityDetect.GetValue(InvisibilityType(i));
1711 
1712  // Too low value to detect
1713  if (ownInvisibilityDetectValue < objInvisibilityValue)
1714  return false;
1715  }
1716 
1717  return true;
1718 }
1719 
1720 bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) const
1721 {
1722  // Combat reach is the minimal distance (both in front and behind),
1723  // and it is also used in the range calculation.
1724  // One stealth point increases the visibility range by 0.3 yard.
1725 
1726  if (!obj->m_stealth.GetFlags())
1727  return true;
1728 
1729  float distance = GetExactDist(obj);
1730  float combatReach = 0.0f;
1731 
1732  Unit const* unit = ToUnit();
1733  if (unit)
1734  combatReach = unit->GetCombatReach();
1735 
1736  if (distance < combatReach)
1737  return true;
1738 
1739  if (!HasInArc(float(M_PI), obj))
1740  return false;
1741 
1742  GameObject const* go = obj->ToGameObject();
1743  for (uint32 i = 0; i < TOTAL_STEALTH_TYPES; ++i)
1744  {
1745  if (!(obj->m_stealth.GetFlags() & (1 << i)))
1746  continue;
1747 
1749  return true;
1750 
1751  // Starting points
1752  int32 detectionValue = 30;
1753 
1754  // Level difference: 5 point / level, starting from level 1.
1755  // There may be spells for this and the starting points too, but
1756  // not in the DBCs of the client.
1757  detectionValue += int32(getLevelForTarget(obj) - 1) * 5;
1758 
1759  // Apply modifiers
1760  detectionValue += m_stealthDetect.GetValue(StealthType(i));
1761  if (go)
1762  if (Unit* owner = go->GetOwner())
1763  detectionValue -= int32(owner->getLevelForTarget(this) - 1) * 5;
1764 
1765  detectionValue -= obj->m_stealth.GetValue(StealthType(i));
1766 
1767  // Calculate max distance
1768  float visibilityRange = float(detectionValue) * 0.3f + combatReach;
1769 
1770  // If this unit is an NPC then player detect range doesn't apply
1771  if (unit && unit->GetTypeId() == TYPEID_PLAYER && visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE)
1772  visibilityRange = MAX_PLAYER_STEALTH_DETECT_RANGE;
1773 
1774  // When checking for alert state, look 8% further, and then 1.5 yards more than that.
1775  if (checkAlert)
1776  visibilityRange += (visibilityRange * 0.08f) + 1.5f;
1777 
1778  // If checking for alert, and creature's visibility range is greater than aggro distance, No alert
1779  Unit const* tunit = obj->ToUnit();
1780  if (checkAlert && unit && unit->ToCreature() && visibilityRange >= unit->ToCreature()->GetAttackDistance(tunit) + unit->ToCreature()->m_CombatDistance)
1781  return false;
1782 
1783  if (distance > visibilityRange)
1784  return false;
1785  }
1786 
1787  return true;
1788 }
1789 
1790 void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf)
1791 {
1792  WorldPacket data(SMSG_PLAY_SOUND, 4);
1793  data << Sound;
1794  if (OnlySelf && GetTypeId() == TYPEID_PLAYER)
1795  ToPlayer()->GetSession()->SendPacket(&data);
1796  else
1797  SendMessageToSet(&data, true); // ToSelf ignored in this case
1798 }
1799 
1801 {
1802  m_uint32Values_mirror[i] = GetUInt32Value(i) + 1; // makes server think the field changed
1803  if (m_inWorld)
1804  {
1805  if (!m_objectUpdated)
1806  {
1808  m_objectUpdated = true;
1809  }
1810  }
1811 }
1812 
1813 namespace Oregon
1814 {
1816 {
1817  public:
1818  MonsterChatBuilder(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID)
1819  : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_targetGUID(targetGUID) {}
1820  void operator()(WorldPacket& data, int32 loc_idx)
1821  {
1822  char const* text = sObjectMgr.GetOregonString(i_textId, loc_idx);
1823 
1824  // @todo i_object.GetName() also must be localized?
1825  i_object.BuildMonsterChat(&data, i_msgtype, text, i_language, i_object.GetNameForLocaleIdx(loc_idx), i_targetGUID);
1826  }
1827 
1828  private:
1834 };
1835 } // namespace Oregon
1836 
1837 void WorldObject::MonsterSay(int32 textId, uint32 language, uint64 TargetGuid)
1838 {
1840 
1841  Cell cell(p);
1842  cell.SetNoCreate();
1843 
1844  Oregon::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_SAY, textId, language, TargetGuid);
1848  cell.Visit(p, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY));
1849 }
1850 
1851 void WorldObject::MonsterYell(int32 textId, uint32 language, uint64 TargetGuid)
1852 {
1854 
1855  Cell cell(p);
1856  cell.SetNoCreate();
1857 
1858  Oregon::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId, language, TargetGuid);
1862  cell.Visit(p, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_YELL));
1863 }
1864 
1865 void WorldObject::MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
1866 {
1867  Oregon::MonsterChatBuilder say_build(*this, CHAT_MSG_MONSTER_YELL, textId, language, TargetGuid);
1869 
1870  uint32 zoneid = GetZoneId();
1871 
1872  Map::PlayerList const& pList = GetMap()->GetPlayers();
1873  for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
1874  if (itr->GetSource()->GetZoneId() == zoneid)
1875  say_do(itr->GetSource());
1876 }
1877 
1878 void WorldObject::MonsterTextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote)
1879 {
1881 
1882  Cell cell(p);
1883  cell.SetNoCreate();
1884 
1885  Oregon::MonsterChatBuilder say_build(*this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId, LANG_UNIVERSAL, TargetGuid);
1889  cell.Visit(p, message, *GetMap(), *this, sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
1890 }
1891 
1892 void WorldObject::MonsterWhisper(int32 textId, uint64 receiver, bool IsBossWhisper)
1893 {
1894  Player* player = sObjectMgr.GetPlayer(receiver);
1895  if (!player || !player->GetSession())
1896  return;
1897 
1898  uint32 loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
1899  char const* text = sObjectMgr.GetOregonString(textId, loc_idx);
1900 
1901  WorldPacket data(SMSG_MESSAGECHAT, 200);
1902  BuildMonsterChat(&data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, text, LANG_UNIVERSAL, GetName(), receiver);
1903 
1904  player->GetSession()->SendPacket(&data);
1905 }
1906 
1907 void WorldObject::BuildMonsterChat(WorldPacket* data, uint8 msgtype, char const* text, uint32 language, char const* name, uint64 targetGuid) const
1908 {
1909  *data << (uint8)msgtype;
1910  *data << (uint32)language;
1911  *data << (uint64)GetGUID();
1912  *data << (uint32)0; //2.1.0
1913  *data << (uint32)(strlen(name) + 1);
1914  *data << name;
1915  *data << (uint64)targetGuid; //Unit Target
1916  if (targetGuid && !IS_PLAYER_GUID(targetGuid))
1917  {
1918  *data << (uint32)1; // target name length
1919  *data << (uint8)0; // target name
1920  }
1921  *data << (uint32)(strlen(text) + 1);
1922  *data << text;
1923  *data << (uint8)0; // ChatTag
1924 }
1925 
1927 {
1928  data->Initialize(MSG_MOVE_HEARTBEAT, 32);
1929  *data << GetPackGUID();
1930  BuildMovementPacket(data);
1931 }
1932 
1933 void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*bToSelf*/)
1934 {
1935  Oregon::MessageDistDeliverer notifier(this, data, dist);
1936  VisitNearbyWorldObject(dist, notifier);
1937 }
1938 
1940 {
1942  data << uint64(guid);
1943  SendMessageToSet(&data, true);
1944 }
1945 
1947 {
1949  data << uint64(guid);
1950  data << uint32(anim);
1951  SendMessageToSet(&data, true);
1952 }
1953 
1955 {
1956  ASSERT(map);
1958  if (m_currMap == map) // command add npc: first create, than loadfromdb
1959  return;
1960  if (m_currMap)
1961  {
1962  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());
1963  ASSERT(false);
1964  }
1965  m_currMap = map;
1966  m_mapId = map->GetId();
1967  m_InstanceId = map->GetInstanceId();
1968  if (IsWorldObject())
1969  m_currMap->AddWorldObject(this);
1970 }
1971 
1973 {
1974  ASSERT(m_currMap);
1975  ASSERT(!IsInWorld());
1976  if (IsWorldObject())
1978  m_currMap = NULL;
1979  //maybe not for corpse
1980  //m_mapId = 0;
1981  //m_InstanceId = 0;
1982 }
1983 
1985 {
1986  ASSERT(m_currMap);
1987  return m_currMap->GetParent();
1988 }
1989 
1991 {
1993 
1994  Map* map = FindMap();
1995  if (!map)
1996  {
1997  sLog.outError("Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list has invalid map (Id: %u).", GetTypeId(), GetEntry(), GetGUIDLow(), GetMapId());
1998  return;
1999  }
2000 
2001  map->AddObjectToRemoveList(this);
2002 }
2003 
2004 TempSummon* Map::SummonCreature(uint32 entry, const Position& pos, SummonPropertiesEntry const* properties, uint32 duration, Unit* summoner, uint32 spellId, TempSummonType spwType)
2005 {
2006  uint32 mask = UNIT_MASK_SUMMON;
2007  if (properties)
2008  {
2009  switch (properties->Category)
2010  {
2011  case SUMMON_CATEGORY_PET:
2012  mask = UNIT_MASK_GUARDIAN;
2013  break;
2015  mask = UNIT_MASK_PUPPET;
2016  break;
2017  case SUMMON_CATEGORY_WILD:
2018  case SUMMON_CATEGORY_ALLY:
2019  {
2020  switch (properties->Type)
2021  {
2022  case SUMMON_TYPE_MINION:
2023  case SUMMON_TYPE_GUARDIAN:
2024  case SUMMON_TYPE_GUARDIAN2:
2025  mask = UNIT_MASK_GUARDIAN;
2026  break;
2027  case SUMMON_TYPE_TOTEM:
2028  mask = UNIT_MASK_TOTEM;
2029  break;
2030  case SUMMON_TYPE_MINIPET:
2031  mask = UNIT_MASK_MINION;
2032  break;
2033  default:
2034  if (properties->Flags & 512)
2035  mask = UNIT_MASK_GUARDIAN;
2036  break;
2037  }
2038  break;
2039  }
2040  default:
2041  return NULL;
2042  }
2043  }
2044 
2045  uint32 team = 0;
2046  if (summoner && summoner->GetTypeId() == TYPEID_PLAYER)
2047  team = summoner->ToPlayer()->GetTeam();
2048 
2049  TempSummon* summon = NULL;
2050  switch (mask)
2051  {
2052  case UNIT_MASK_SUMMON:
2053  summon = new TempSummon(properties, summoner, false);
2054  break;
2055  case UNIT_MASK_GUARDIAN:
2056  summon = new Guardian(properties, summoner, false);
2057  break;
2058  case UNIT_MASK_PUPPET:
2059  summon = new Puppet(properties, summoner);
2060  break;
2061  case UNIT_MASK_TOTEM:
2062  summon = new Totem(properties, summoner);
2063  break;
2064  case UNIT_MASK_MINION:
2065  summon = new Minion(properties, summoner, false);
2066  break;
2067  default:
2068  return NULL;
2069  }
2070 
2071  if (!summon->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT), this, PHASEMASK_NORMAL, entry, team, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
2072  {
2073  delete summon;
2074  return NULL;
2075  }
2076 
2077  summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
2078  summon->SetHomePosition(pos);
2079  // CreatureAI::Reset was already called, check if TempSummonType changed, if
2080  // so, don't touch it or we may mess up the script. (Example Script: Inferno)
2081  // TEMPSUMMON_MANUL_DESPAWN is the default one so we check against it.
2083  summon->SetTempSummonType(spwType);
2084  summon->InitStats(duration);
2085  AddToMap(summon->ToCreature());
2086  summon->InitSummon();
2087 
2088  return summon;
2089 }
2090 
2092 {
2093  if (Map* map = FindMap())
2094  {
2095  if (TempSummon* summon = map->SummonCreature(entry, pos, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL, NULL, spwtype))
2096  return summon;
2097  }
2098 
2099  return NULL;
2100 }
2101 
2103 {
2104  if (Map* map = FindMap())
2105  {
2106  if (map->IsDungeon())
2107  m_zoneScript = (ZoneScript*)((InstanceMap*)map)->GetInstanceData();
2108  else if (!map->IsBattlegroundOrArena())
2109  m_zoneScript = sOutdoorPvPMgr.GetZoneScript(GetZoneId());
2110  }
2111 }
2112 
2113 Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration)
2114 {
2115  Pet* pet = new Pet(this, petType);
2116  SetPetStatus(PET_STATUS_CURRENT);
2117 
2118  if (petType == SUMMON_PET && pet->LoadPetFromDB(this, entry))
2119  {
2120  // Remove Demonic Sacrifice auras (known pet)
2121  Unit::AuraList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
2122  for (Unit::AuraList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();)
2123  {
2124  if ((*itr)->GetModifier()->m_miscvalue == 2228)
2125  {
2126  RemoveAurasDueToSpell((*itr)->GetId());
2127  itr = auraClassScripts.begin();
2128  }
2129  else
2130  ++itr;
2131  }
2132 
2133  if (duration > 0)
2134  pet->SetDuration(duration);
2135 
2136  return NULL;
2137  }
2138 
2139  // petentry == 0 for hunter "call pet" (current pet summoned if any)
2140  if (!entry)
2141  {
2142  delete pet;
2143  return NULL;
2144  }
2145 
2146  Map* map = GetMap();
2147  uint32 pet_number = sObjectMgr.GeneratePetNumber();
2148  if (!pet->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_PET), map, GetPhaseMask(), entry, pet_number))
2149  {
2150  sLog.outError("no such creature entry %u", entry);
2151  delete pet;
2152  return NULL;
2153  }
2154 
2155  pet->Relocate(x, y, z, ang);
2156  if (!pet->IsPositionValid())
2157  {
2158  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());
2159  delete pet;
2160  return NULL;
2161  }
2162 
2163  pet->SetCreatorGUID(GetGUID());
2164  pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, GetFaction());
2165 
2166  // this enables pet details window (Shift+P)
2167  pet->GetCharmInfo()->SetPetNumber(pet_number, false);
2168 
2169  pet->setPowerType(POWER_MANA);
2170  pet->SetUInt32Value(UNIT_NPC_FLAGS , 0);
2172  pet->InitStatsForLevel(getLevel());
2173 
2174  SetMinion(pet, true);
2175 
2176  switch (petType)
2177  {
2178  case CLASS_PET:
2179  case SUMMON_PET:
2180  pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
2183  pet->SetHealth(pet->GetMaxHealth());
2186  default:
2187  break;
2188  }
2189 
2190  map->AddToMap(pet->ToCreature());
2191 
2192  switch (petType)
2193  {
2194  case CLASS_PET:
2195  case SUMMON_PET:
2196  pet->InitPetCreateSpells();
2198  PetSpellInitialize();
2199  default:
2200  break;
2201  }
2202 
2203  if (petType == SUMMON_PET)
2204  {
2205  // Remove Demonic Sacrifice auras (known pet)
2206  Unit::AuraList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
2207  for (Unit::AuraList::const_iterator itr = auraClassScripts.begin(); itr != auraClassScripts.end();)
2208  {
2209  if ((*itr)->GetModifier()->m_miscvalue == 2228)
2210  {
2211  RemoveAurasDueToSpell((*itr)->GetId());
2212  itr = auraClassScripts.begin();
2213  }
2214  else
2215  ++itr;
2216  }
2217  }
2218 
2219  if (duration > 0)
2220  pet->SetDuration(duration);
2221 
2222  return pet;
2223 }
2224 
2225 GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
2226 {
2227  if (!IsInWorld())
2228  return NULL;
2229 
2230  GameObjectInfo const* goinfo = sObjectMgr.GetGameObjectInfo(entry);
2231  if (!goinfo)
2232  {
2233  sLog.outErrorDb("Gameobject template %u not found in database!", entry);
2234  return NULL;
2235  }
2236  Map* map = GetMap();
2237  GameObject* go = new GameObject();
2238  if (!go->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, PHASEMASK_NORMAL, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY))
2239  {
2240  delete go;
2241  return NULL;
2242  }
2243  go->SetRespawnTime(respawnTime);
2244  if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT) //not sure how to handle this
2245  ((Unit*)this)->AddGameObject(go);
2246  else
2247  go->SetSpawnedByDefault(false);
2248  map->AddToMap(go);
2249 
2250  return go;
2251 }
2252 
2253 Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint32 duration, CreatureAI * (*GetAI)(Creature*))
2254 {
2255  TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2256  Creature* summon = SummonCreature(WORLD_TRIGGER, x, y, z, ang, summonType, duration);
2257  if (!summon)
2258  return NULL;
2259 
2260  //summon->SetName(GetName());
2261  if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT)
2262  {
2263  summon->SetFaction(((Unit*)this)->GetFaction());
2264  summon->SetLevel(((Unit*)this)->getLevel());
2265  }
2266 
2267  if (GetAI)
2268  summon->AIM_Initialize(GetAI(summon));
2269  return summon;
2270 }
2271 
2278 void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= NULL*/)
2279 {
2280  ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!");
2281 
2282  std::vector<TempSummonData> const* data = sObjectMgr.GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group);
2283  if (!data)
2284  return;
2285 
2286  for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
2287  if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, itr->time))
2288  if (list)
2289  list->push_back(summon);
2290 }
2291 
2292 Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive)
2293 {
2294  Creature* creature = NULL;
2295  Oregon::NearestCreatureEntryWithLiveStateInObjectRangeCheck checker(*this, entry, alive, range);
2297  VisitNearbyObject(range, searcher);
2298  return creature;
2299 }
2300 
2302 {
2303  GameObject* go = NULL;
2304  Oregon::NearestGameObjectEntryInObjectRangeCheck checker(*this, entry, range);
2306  VisitNearbyGridObject(range, searcher);
2307  return go;
2308 }
2309 
2311 {
2312  GameObject* go = NULL;
2313  Oregon::NearestGameObjectTypeInObjectRangeCheck checker(*this, type, range);
2315  VisitNearbyGridObject(range, searcher);
2316  return go;
2317 }
2318 
2319 void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameobjectList, uint32 entry, float maxSearchRange) const
2320 {
2322  Cell cell(pair);
2323  cell.SetNoCreate();
2324 
2325  Oregon::AllGameObjectsWithEntryInRange check(this, entry, maxSearchRange);
2326  Oregon::GameObjectListSearcher<Oregon::AllGameObjectsWithEntryInRange> searcher(this, gameobjectList, check);
2328 
2329  cell.Visit(pair, visitor, *(this->GetMap()), *this, maxSearchRange);
2330 }
2331 
2332 void WorldObject::GetCreatureListWithEntryInGrid(std::list<Creature*>& creatureList, uint32 entry, float maxSearchRange) const
2333 {
2335  Cell cell(pair);
2336  cell.SetNoCreate();
2337 
2338  Oregon::AllCreaturesOfEntryInRange check(this, entry, maxSearchRange);
2339  Oregon::CreatureListSearcher<Oregon::AllCreaturesOfEntryInRange> searcher(this, creatureList, check);
2341 
2342  cell.Visit(pair, visitor, *(this->GetMap()), *this, maxSearchRange);
2343 }
2344 
2345 void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float absAngle) const
2346 {
2347  x = GetPositionX() + (GetObjectSize() + distance2d) * cos(absAngle);
2348  y = GetPositionY() + (GetObjectSize() + distance2d) * sin(absAngle);
2349 
2352 }
2353 
2354 void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle) const
2355 {
2356  GetNearPoint2D(x, y, distance2d + searcher_size, absAngle);
2357  z = GetPositionZ();
2358  UpdateAllowedPositionZ(x, y, z);
2359 }
2360 
2361 Position WorldObject::GetNearPosition(float dist, float angle)
2362 {
2363  Position pos = GetPosition();
2364  MovePosition(pos, dist, angle);
2365  return pos;
2366 }
2367 
2369 {
2370  Position pos = GetPosition();
2371  MovePositionToFirstCollision(pos, dist, angle);
2372  return pos;
2373 }
2374 
2376 {
2377  Position pos = GetPosition();
2378  MovePosition(pos, radius * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI));
2379  return pos;
2380 }
2381 
2382 // @todo: replace with WorldObject::UpdateAllowedPositionZ
2383 // To use WorldObject::UpdateAllowedPositionZ at the moment causes a caster of
2384 // a leap effect to fall through the ground much too easily.
2385 float WorldObject::GetPositionZTarget(Position& pos, float destx, float desty)
2386 {
2387 
2388  // Added in Bitbucket issue #1105 in order to solve the problem of
2389  // leap effects like Blink taking the caster to the bottom of a body of liquid.
2390 
2391  float bottom, ground, floor;
2392 
2393  ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
2394  floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
2395  // If we were to ignore liquid, the WorldObject would be placed here.
2396  bottom = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
2397 
2398  if(pos.m_positionZ > bottom)
2399  {
2400 
2401  // We are in the water or in the air.
2402  // Must be at least above ground.
2403 
2404  LiquidData dest_status;
2405  GetMap()->getLiquidStatus(destx, desty, pos.m_positionZ, MAP_ALL_LIQUIDS, &dest_status);
2406 
2407  // Source and destination are underwater.
2408  if(dest_status.level > pos.m_positionZ)
2409  return pos.m_positionZ;
2410 
2411  // When in doubt, send the user to water/ground level.
2412  return fabs(dest_status.level - pos.m_positionZ) <= fabs(bottom - pos.m_positionZ) ? dest_status.level : bottom;
2413 
2414  }
2415  else
2416  {
2417  // Destination is on or under the ground. Use ground Z.
2418  return bottom;
2419  }
2420 }
2421 
2422 void WorldObject::MovePosition(Position& pos, float dist, float angle)
2423 {
2424  angle += GetOrientation();
2425  float destx, desty, destz, ground, floor;
2426  destx = pos.m_positionX + dist * cos(angle);
2427  desty = pos.m_positionY + dist * sin(angle);
2428 
2429  // Prevent invalid coordinates here, position is unchanged
2430  if (!Oregon::IsValidMapCoord(destx, desty, pos.m_positionZ))
2431  {
2432  sLog.outString("WorldObject::MovePosition invalid coordinates X: %f and Y: %f were passed!", destx, desty);
2433  return;
2434  }
2435 
2436  // Prevent invalid coordinates here, position is unchanged
2437  if (!Oregon::IsValidMapCoord(destx, desty))
2438  {
2439  sLog.outError("Crash alert! WorldObject::MovePositionToFirstCollision invalid coordinates X: %f and Y: %f were passed!", destx, desty);
2440  return;
2441  }
2442 
2443  ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
2444  floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
2445  destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
2446 
2447  float step = dist / 10.0f;
2448 
2449  for (uint8 j = 0; j < 10; ++j)
2450  {
2451  // do not allow too big z changes
2452  if (fabs(pos.m_positionZ - destz) > 6)
2453  {
2454  destx -= step * cos(angle);
2455  desty -= step * sin(angle);
2456  ground = GetMap()->GetHeight(destx, desty, MAX_HEIGHT, true);
2457  floor = GetMap()->GetHeight(destx, desty, pos.m_positionZ, true);
2458  destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
2459  }
2460  // we have correct destz now
2461  else
2462  {
2463  pos.Relocate(destx, desty, destz);
2464  break;
2465  }
2466  }
2467 
2472 }
2473 
2474 void WorldObject::MovePositionToFirstCollision(Position& pos, float dist, float angle)
2475 {
2476  angle += GetOrientation();
2477  float destx, desty, destz;
2478  destx = pos.m_positionX + dist * cos(angle);
2479  desty = pos.m_positionY + dist * sin(angle);
2480 
2481  // Prevent invalid coordinates here, position is unchanged
2482  if (!Oregon::IsValidMapCoord(destx, desty))
2483  {
2484  sLog.outFatal("WorldObject::MovePositionToFirstCollision invalid coordinates X: %f and Y: %f were passed!", destx, desty);
2485  return;
2486  }
2487 
2488  destz = GetPositionZTarget(pos, destx, desty);
2489  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);
2490 
2491  // collision occured
2492  if (col)
2493  {
2494  // move back a bit
2495  destx -= CONTACT_DISTANCE * cos(angle);
2496  desty -= CONTACT_DISTANCE * sin(angle);
2497  dist = sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
2498  }
2499 
2500  // check dynamic collision
2501  col = GetMap()->getObjectHitPos(pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
2502 
2503  // Collided with a gameobject
2504  if (col)
2505  {
2506  destx -= CONTACT_DISTANCE * cos(angle);
2507  desty -= CONTACT_DISTANCE * sin(angle);
2508  dist = sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
2509  }
2510 
2511  float step = dist / 10.0f;
2512 
2513  for (uint8 j = 0; j < 10; ++j)
2514  {
2515  // do not allow too big z changes
2516  if (fabs(pos.m_positionZ - destz) > 6.0f)
2517  {
2518  destx -= step * cos(angle);
2519  desty -= step * sin(angle);
2520  destz = GetPositionZTarget(pos, destx, desty);
2521  }
2522  // we have correct destz now
2523  else
2524  {
2525  pos.Relocate(destx, desty, destz);
2526  break;
2527  }
2528  }
2529 
2532  pos.m_positionZ = GetPositionZTarget(pos, destx, desty);
2534 }
2535 
2536 void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
2537 {
2538  m_phaseMask = newPhaseMask;
2539 
2540  if (update && IsInWorld())
2542 }
2543 
2544 void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
2545 {
2546  WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8);
2547  data << uint32(sound_id);
2548  data << uint64(GetGUID());
2549  if (target)
2550  target->SendDirectMessage(&data);
2551  else
2552  SendMessageToSet(&data, true);
2553 }
2554 
2555 void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/)
2556 {
2557  WorldPacket data(SMSG_PLAY_SOUND, 4);
2558  data << uint32(sound_id);
2559  if (target)
2560  target->SendDirectMessage(&data);
2561  else
2562  SendMessageToSet(&data, true);
2563 }
2564 
2566 {
2567  if (!IsInWorld())
2568  return;
2569 
2570  std::list<Player*> targets;
2574  for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
2575  {
2576  Player* player = (*iter);
2577 
2578  if (player == this)
2579  continue;
2580 
2581  if (!player->HaveAtClient(this))
2582  continue;
2583 
2584  if (isType(TYPEMASK_UNIT) && ((Unit*)this)->GetCharmerGUID() == player->GetGUID()) // @todo this is for puppet
2585  continue;
2586 
2587  if (GetTypeId() == TYPEID_UNIT)
2588  {
2589  // at remove from world (destroy) show kill animation
2590  DestroyForPlayer(player, ToUnit()->IsDuringRemoveFromWorld() && ToCreature()->isDead());
2591  }
2592  else
2593  DestroyForPlayer(player);
2594 
2595  player->m_clientGUIDs.erase(GetGUID());
2596  }
2597 }
2598 
2600 {
2601  //updates object's visibility for nearby players
2602  Oregon::VisibleChangesNotifier notifier(*this);
2604 }
2605 
2607 {
2610  std::set<uint64> plr_list;
2611  WorldObjectChangeAccumulator(WorldObject& obj, UpdateDataMapType& d) : i_updateDatas(d), i_object(obj) {}
2613  {
2614  for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
2615  {
2616  BuildPacket(iter->GetSource());
2617  if (!iter->GetSource()->GetSharedVisionList().empty())
2618  {
2619  SharedVisionList::const_iterator it = iter->GetSource()->GetSharedVisionList().begin();
2620  for (; it != iter->GetSource()->GetSharedVisionList().end(); ++it)
2621  BuildPacket(*it);
2622  }
2623  }
2624  }
2625 
2627  {
2628  for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
2629  {
2630  if (!iter->GetSource()->GetSharedVisionList().empty())
2631  {
2632  SharedVisionList::const_iterator it = iter->GetSource()->GetSharedVisionList().begin();
2633  for (; it != iter->GetSource()->GetSharedVisionList().end(); ++it)
2634  BuildPacket(*it);
2635  }
2636  }
2637  }
2639  {
2640  for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
2641  {
2642  uint64 guid = iter->GetSource()->GetCasterGUID();
2643  if (IS_PLAYER_GUID(guid))
2644  {
2645  //Caster may be NULL if DynObj is in removelist
2646  if (Player* caster = ObjectAccessor::FindPlayer(guid))
2647  if (caster->GetUInt64Value(PLAYER_FARSIGHT) == iter->GetSource()->GetGUID())
2648  BuildPacket(caster);
2649  }
2650  }
2651  }
2652  void BuildPacket(Player* plr)
2653  {
2654  // Only send update once to a player
2655  if (plr_list.find(plr->GetGUID()) == plr_list.end() && plr->HaveAtClient(&i_object))
2656  {
2657  i_object.BuildFieldsUpdate(plr, i_updateDatas);
2658  plr_list.insert(plr->GetGUID());
2659  }
2660  }
2661 
2662  template<class SKIP> void Visit(GridRefManager<SKIP>&) {}
2663 };
2664 
2666 {
2668  Cell cell(p);
2669  cell.SetNoCreate();
2670  WorldObjectChangeAccumulator notifier(*this, data_map);
2672  Map& map = *GetMap();
2673  //we must build packets for all visible players
2674  cell.Visit(p, player_notifier, map, *this, GetVisibilityRange());
2675 
2676  ClearUpdateMask(false);
2677 }
2678 
despawns when UnSummon() is called
float GetGridActivationRange() const
Definition: Object.cpp:1531
void MovePosition(Position &pos, float dist, float angle)
Definition: Object.cpp:2422
GameobjectTypes
bool BuildPacket(WorldPacket *packet, bool hasTransport=false)
Definition: UpdateData.cpp:103
virtual void ResetMap()
Definition: Object.cpp:1972
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:1162
void SetStatFloatValue(uint16 index, float value)
Definition: Object.cpp:930
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:2225
void SendPlaySound(uint32 Sound, bool OnlySelf)
Definition: Object.cpp:1790
Definition: Corpse.h:48
PetType
Definition: Pet.h:25
float s_pitch
Definition: Object.h:464
const bool m_isWorldObject
Definition: Object.h:933
T_FLAGS GetFlags() const
Definition: Object.h:620
bool GetBit(uint32 index)
Definition: UpdateMask.h:49
bool m_objectUpdated
Definition: Object.h:440
const uint32 & GetUInt32Value(uint16 index) const
Definition: Object.h:234
virtual bool IsNeverVisible() const
Definition: Object.h:816
Unit * GetOwner() const
Definition: GameObject.cpp:783
void ApplyModUInt32Value(uint16 index, int32 val, bool apply)
Definition: Object.cpp:946
void _BuildMovementUpdate(ByteBuffer *data, uint8 updateFlags) const
Definition: Object.cpp:253
Map * m_currMap
Definition: Object.h:949
virtual void SetPhaseMask(uint32 newPhaseMask, bool update)
Definition: Object.cpp:2536
void ClearUpdateMask(bool remove)
Definition: Object.cpp:678
void SetPetNumber(uint32 petnumber, bool statwindow)
Definition: Unit.cpp:11393
uint32 GetMaxHealth() const
Definition: Unit.h:1075
bool m_inWorld
Definition: Object.h:443
bool _IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D) const
Definition: Object.cpp:1213
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition: Object.cpp:1276
uint32 * m_uint32Values
Definition: Object.h:432
#define sOutdoorPvPMgr
Definition: OutdoorPvPMgr.h:79
void PlayDirectSound(uint32 sound_id, Player *target=NULL)
Definition: Object.cpp:2555
float GetTransOffsetZ() const
Definition: Player.h:2408
int32 * m_int32Values
Definition: Object.h:431
Map * GetMap() const
Definition: Object.h:841
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:2113
void SendObjectCustomAnim(uint64 guid, uint32 anim=0)
Definition: Object.cpp:1946
#define DEFAULT_VISIBILITY_INSTANCE
Definition: Object.h:41
uint32 GetFaction() const
Definition: Unit.h:1116
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const
Definition: Unit.cpp:846
uint32 GetUnitMovementFlags() const
Definition: Unit.h:1904
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition: Object.cpp:2310
void Visit(DynamicObjectMapType &m)
Definition: Object.cpp:2638
void MonsterTextEmote(const char *text, uint64 TargetGuid, bool IsBossEmote=false)
Definition: Object.cpp:1504
Position GetFirstCollisionPosition(float dist, float angle)
Definition: Object.cpp:2368
void MonsterSay(const char *text, uint32 language, uint64 TargetGuid)
Definition: Object.cpp:1490
float m_positionY
Definition: Position.h:51
float GetDistanceSqr(float x, float y, float z) const
Definition: Object.cpp:1203
bool LoadValues(const char *data)
Definition: Object.cpp:704
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:927
void BuildFieldsUpdate(Player *, UpdateDataMapType &) const
Definition: Object.cpp:690
void SetInt32Value(uint16 index, int32 value)
Definition: Object.cpp:760
std::set< uint64 > plr_list
Definition: Object.cpp:2610
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1419
bool isType(uint16 mask) const
Definition: Object.h:214
void setActive(bool isActiveObject)
Definition: Object.cpp:1123
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition: Object.h:833
#define WORLD_TRIGGER
Definition: Unit.h:38
uint32 GetZoneId() const
Definition: Object.cpp:1179
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0)
Definition: Object.cpp:2091
void BuildMovementUpdateBlock(UpdateData *data, uint32 flags=0) const
Definition: Object.cpp:136
void ApplyModInt32Value(uint16 index, int32 val, bool apply)
Definition: Object.cpp:955
virtual void SetMap(Map *map)
Definition: Object.cpp:1954
bool CanNeverSee(WorldObject const *obj) const
Definition: Object.cpp:1663
uint32 getMSTime()
Definition: Timer.h:32
void _LoadIntoDataField(const char *data, uint32 startOffset, uint32 count)
Definition: Object.cpp:721
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:626
#define sLog
Log class singleton.
Definition: Log.h:187
float GetVisibilityRange() const
Definition: Object.cpp:1552
ChatMsg
virtual void CleanupsBeforeDelete()
Definition: Object.cpp:1156
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:2332
Tokens StrSplit(const std::string &src, const std::string &sep)
Definition: Util.cpp:58
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:779
ACE_INT32 int32
Definition: Define.h:67
bool IsWithinLOSInMap(const WorldObject *obj) const
Definition: Object.cpp:1229
std::list< Aura * > AuraList
Definition: Unit.h:917
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:719
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:2319
bool IsDungeon() const
Definition: Map.h:427
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibilityDetect
Definition: Object.h:831
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:1243
bool IsWorldObject() const
Definition: Object.cpp:1112
void SetNoCreate()
Definition: Cell.h:76
void RemoveWorldObject(WorldObject *obj)
Definition: Map.h:483
bool IsGameMaster() const
Definition: Player.h:1009
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:693
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealthDetect
Definition: Object.h:828
uint32 GetGUIDLow() const
Definition: Object.h:166
void MonsterYell(const char *text, uint32 language, uint64 TargetGuid)
Definition: Object.cpp:1497
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:407
void SetStatInt32Value(uint16 index, int32 value)
Definition: Object.cpp:938
static uint32 GetAreaId(uint16 areaflag, uint32 map_id)
Definition: Map.cpp:1822
UpdateDataMapType & i_updateDatas
Definition: Object.cpp:2608
#define SIGHT_RANGE_UNIT
Definition: Object.h:39
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:985
TempSummonType GetTempSummonType() const
uint32 modelid1
Definition: Creature.h:134
bool AIM_Initialize(CreatureAI *ai=NULL)
Definition: Creature.cpp:746
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:424
void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:969
bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const
Definition: Object.cpp:1344
#define sObjectMgr
Definition: ObjectMgr.h:1285
void SendPacket(WorldPacket const *packet)
GameObject * ToGameObject()
Definition: Object.h:401
CharmInfo * GetCharmInfo()
Definition: Unit.h:1458
void setPowerType(Powers power)
Definition: Unit.cpp:7144
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition: Object.h:789
void VisitNearbyGridObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:922
uint32 m_InstanceId
Definition: Object.h:952
virtual void _SetUpdateBits(UpdateMask *updateMask, Player *target) const
Definition: Object.cpp:737
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition: Object.h:921
InvisibilityType
Player * ToPlayer()
Definition: Object.h:392
void MonsterWhisper(const char *text, uint64 receiver, bool IsBossWhisper=false)
Definition: Object.cpp:1511
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:1029
uint32 flags_extra
Definition: Creature.h:195
virtual void RemoveFromWorld()
Definition: Object.h:151
Definition: Totem.h:31
bool ShouldRevealHealthTo(Player *player) const
Definition: Unit.cpp:10966
virtual uint8 getLevelForTarget(WorldObject const *) const
Definition: Object.h:792
virtual bool IsInvisibleDueToDespawn() const
Definition: Object.h:818
uint8 m_objectTypeId
Definition: Object.h:426
uint32 GetId(void) const
Definition: Map.h:333
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition: Object.h:770
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:1324
despawns after a specified time
uint8 * GetMask()
Definition: UpdateMask.h:66
uint8 GetTypeId() const
Definition: Object.h:210
void SavePetToDB(PetSaveMode mode)
Definition: Pet.cpp:364
uint32 m_mapId
Definition: Object.h:596
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:2385
Position GetHitSpherePointFor(Position const &dest) const
Definition: Object.cpp:1259
bool InitStatsForLevel(uint32 level)
Definition: Pet.cpp:967
CinematicMgr * GetCinematicMgr() const
Definition: Player.h:1257
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:817
Position GetNearPosition(float dist, float angle)
Definition: Object.cpp:2361
PackedGuid m_PackGUID
Definition: Object.h:445
const bool & IsInWorld() const
Definition: Object.h:135
void BuildUpdate(UpdateDataMapType &) override
Definition: Object.cpp:2665
void ApplyModSignedFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:962
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:934
void AddObjectToRemoveList()
Definition: Object.cpp:1990
void BuildPacket(Player *plr)
Definition: Object.cpp:2652
uint32 GetPhaseMask() const
Definition: Object.h:694
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:436
Map * FindMap() const
Definition: Object.h:842
bool RemoveUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:838
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:2004
void AddUpdateObject(Object *obj)
float GetPositionY() const
Definition: Position.h:98
uint8 m_updateFlag
Definition: Object.h:427
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:878
virtual bool isValid() const
Definition: Object.cpp:1523
void SetSpawnedByDefault(bool b)
Definition: GameObject.h:709
#define MAKE_NEW_GUID(l, e, h)
Definition: ObjectGuid.h:80
Position GetRandomNearPosition(float radius)
Definition: Object.cpp:2375
void SetUInt16Value(uint16 index, uint8 offset, uint16 value)
Definition: Object.cpp:904
void GetPosition(float &x, float &y) const
Definition: Position.h:102
float level
Definition: Map.h:151
bool m_isActive
Definition: Object.h:932
virtual void RemoveFromWorld() override
Definition: Object.cpp:1169
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition: Object.h:834
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:1054
float GetPositionZ() const
Definition: Position.h:99
void ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
Definition: Object.cpp:976
bool isActiveObject() const
Definition: Object.h:911
bool CanDetect(WorldObject const *obj, bool ignoreStealth, bool checkAlert=false) const
Definition: Object.cpp:1668
float GetTransOffsetY() const
Definition: Player.h:2404
float GetAngle(Position const *pos) const
TempSummonType
bool PrintIndexError(uint32 index, bool set) const
Definition: Object.cpp:1079
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d)
Definition: Object.cpp:2611
void SendDirectMessage(WorldPacket *data)
Definition: Player.cpp:5724
static uint32 GetZoneId(uint16 areaflag, uint32 map_id)
Definition: Map.cpp:1832
PackedGuid const & GetPackGUID() const
Definition: Object.h:178
#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:764
virtual bool CanAlwaysSee(WorldObject const *) const
Definition: Object.h:959
void operator()(WorldPacket &data, int32 loc_idx)
Definition: Object.cpp:1820
float GetAttackDistance(Unit const *pl) const
Definition: Creature.cpp:1537
uint32 GetMapId() const
Definition: Object.h:591
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:2292
Position GetPosition() const
Definition: Position.h:117
bool IsInMap(const WorldObject *obj) const
Definition: Object.h:745
uint32 GetAreaId() const
Definition: Object.cpp:1184
StealthType
UNORDERED_MAP< Player *, UpdateData > UpdateDataMapType
Definition: Object.h:126
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:798
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:167
void MonsterYellToZone(int32 textId, uint32 language, uint64 TargetGuid)
Definition: Object.cpp:1865
void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const
Definition: Object.cpp:2345
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:2474
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:704
void ApplyPercentModFloatVar(float &var, float val, bool apply)
Definition: Util.h:88
~WorldObject() override
Definition: Object.cpp:81
void ForceValuesUpdateAtIndex(uint32)
Definition: Object.cpp:1800
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:1006
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:1802
void Visit(CreatureMapType &m)
Definition: Object.cpp:2626
bool IsInRange(WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
Definition: Object.cpp:1299
uint64 GetPetGUID() const
Definition: Unit.h:1378
bool CanDetectStealthOf(WorldObject const *obj, bool checkAlert=false) const
Definition: Object.cpp:1720
bool isAllowedToLoot(const Creature *creature)
Definition: Player.cpp:15038
#define MAX_PLAYER_STEALTH_DETECT_RANGE
Definition: Unit.h:904
Definition: Unit.h:485
void BuildHeartBeatMsg(WorldPacket *data) const
Definition: Object.cpp:1926
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:18687
bool isDead() const
Definition: Unit.h:1338
bool HasInArc(float arcangle, const Position *pos) const
Definition: Object.cpp:1393
WorldObject(bool isWorldObject)
Definition: Object.cpp:1087
CreatureInfo const * GetCreatureTemplate() const
Definition: Creature.h:557
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1410
void AddUpdateBlock(const ByteBuffer &block)
Definition: UpdateData.cpp:41
virtual void InitSummon()
Map const * GetBaseMap() const
Definition: Object.cpp:1984
#define MAP_ALL_LIQUIDS
Definition: Map.h:142
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=NULL)
Definition: Object.cpp:2278
static void WriteCreate(const MoveSpline &mov, ByteBuffer &data)
void SendObjectDeSpawnAnim(uint64 guid)
Definition: Object.cpp:1939
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:1907
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const
Definition: Object.cpp:749
bool LoadPetFromDB(Player *owner, uint32 petentry=0, uint32 petnumber=0, bool current=false)
Definition: Pet.cpp:131
Creature * ToCreature()
Definition: Object.h:395
virtual void UpdateObjectVisibility(bool forced=true)
Definition: Object.cpp:2599
void SetZoneScript()
Definition: Object.cpp:2102
float m_SightDistance
Definition: Creature.h:789
void SetFaction(uint32 faction)
Definition: Unit.h:1117
void AddToActive(T *obj)
Definition: Map.h:502
float * m_floatValues
Definition: Object.h:433
Creature * SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI *(*GetAI)(Creature *)=NULL)
Definition: Object.cpp:2253
uint32 GetGUIDHigh() const
Definition: Object.h:174
void SetWorldObject(bool apply)
Definition: Object.cpp:1104
void SetFloatValue(uint16 index, float value)
Definition: Object.cpp:859
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:1398
void SetCount(uint32 valuesCount)
Definition: UpdateMask.h:71
uint32 m_phaseMask
Definition: Object.h:953
uint16 m_valuesCount
Definition: Object.h:438
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:1933
uint32 GetFallTime() const
Definition: Object.h:539
uint32 GetTeam() const
Definition: Player.h:2063
void SetPower(Powers power, uint32 val)
Definition: Unit.cpp:10997
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealth
Definition: Object.h:827
static IVMapManager * createOrGetVMapManager()
bool isTappedBy(Player const *player) const
Definition: Creature.cpp:1038
#define ASSERT
Definition: Errors.h:29
GameObject * FindNearestGameObject(uint32 entry, float range)
Definition: Object.cpp:2301
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibility
Definition: Object.h:830
uint32 GetTransTime() const
Definition: Player.h:2416
bool AddUInt64Value(uint16 index, const uint64 &value)
Definition: Object.cpp:817
void SetTempSummonType(TempSummonType type)
void PlayDistanceSound(uint32 sound_id, Player *target=NULL)
Definition: Object.cpp:2544
T_VALUES GetValue(FLAG_TYPE flag) const
Definition: Object.h:625
void DestroyForNearbyPlayers()
Definition: Object.cpp:2565
#define INVALID_HEIGHT
Definition: Map.h:259
void SetLevel(uint32 lvl)
Definition: Unit.cpp:10896
const int32 & GetInt32Value(uint16 index) const
Definition: Object.h:228
virtual void InitStats(uint32 lifetime)
WorldObject const & i_object
Definition: Object.cpp:1829
uint32 GetEntry() const
Definition: Object.h:192
bool IsPositionValid() const
Definition: Position.cpp:40
WorldSession * GetSession() const
Definition: Player.h:1944
#define sWorld
Definition: World.h:860
#define CONTACT_DISTANCE
Definition: Object.h:34
void SetHealth(uint32 val)
Definition: Unit.cpp:10905
void Visit(GridRefManager< SKIP > &)
Definition: Object.cpp:2662
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:1195
void _InitValues()
Definition: Object.cpp:114
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition: Unit.cpp:7187
bool CanSeeOrDetect(WorldObject const *obj, bool ignoreStealth=false, bool distanceCheck=false, bool checkAlert=false) const
Definition: Object.cpp:1585
virtual bool IsAlwaysDetectableFor(WorldObject const *) const
Definition: Object.h:820
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:695
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:789
void BuildOutOfRangeUpdateBlock(UpdateData *data) const
Definition: Object.cpp:236
float GetObjectSize() const
Definition: Object.h:669
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:2354
Definition: Player.h:922
bool CanDetectInvisibilityOf(WorldObject const *obj) const
Definition: Object.cpp:1689
uint32 GetInstanceId() const
Definition: Map.h:390
void Visit(PlayerMapType &m)
Definition: Object.cpp:2612
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:2330
Unit * ToUnit()
Definition: Object.h:398
uint32 GetBlockCount()
Definition: UpdateMask.h:54
float GetSightRange(const WorldObject *target=NULL) const
Definition: Object.cpp:1560
void VisitNearbyWorldObject(const float &radius, NOTIFIER &notifier) const
Definition: Object.h:920
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:1818
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1483
#define atol(a)
Definition: Common.h:162
float GetHealthPct() const
Definition: Unit.h:1085
const uint64 & GetGUID() const
Definition: Object.h:162
InstanceData * GetInstanceData()
Definition: Object.cpp:1189
const float & GetFloatValue(uint16 index) const
Definition: Object.h:246
void NormalizeMapCoord(float &c)
Definition: GridDefines.h:184