Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
Object.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Battlefield.h"
7#include "BattlefieldMgr.h"
8#include "CellImpl.h"
9#include "Chat.h"
10#include "Common.h"
11#include "Creature.h"
12#include "DynamicTree.h"
13#include "GridNotifiers.h"
14#include "GridNotifiersImpl.h"
15#include "Group.h"
16#include "Log.h"
17#include "Log.h"
18#include "MapManager.h"
20#include "Object.h"
21#include "ObjectAccessor.h"
22#include "ObjectMgr.h"
23#include "Opcodes.h"
24#include "OutdoorPvPMgr.h"
25#include "Player.h"
26#include "SharedDefines.h"
27#include "SpellAuraEffects.h"
29#include "TemporarySummon.h"
31#include "Totem.h"
32#include "Transport.h"
33#include "Unit.h"
34#include "UpdateData.h"
35#include "UpdateFieldFlags.h"
36#include "UpdateMask.h"
37#include "Util.h"
38#include "Vehicle.h"
39#include "VMapFactory.h"
41#include "World.h"
42#include "WorldPacket.h"
43
45{
46 switch (guid_hi)
47 {
49 //case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER == HIGHGUID_ITEM currently
60 }
61 return TypeID::NUM_CLIENT_OBJECT_TYPES; // unknown
62}
63
69
71{
72 // this may happen because there are many !create/delete
73 if (IsWorldObject() && m_currMap)
74 {
76 {
77 SF_LOG_FATAL("misc", "Object::~Object Corpse guid=" UI64FMTD ", type=%d, entry=%u deleted but still in map!!",
78 GetGUID(), uint8(((Corpse*)this)->GetType()), GetEntry());
79 ASSERT(false);
80 }
81 ResetMap();
82 }
83}
84
86{
87 if (IsInWorld())
88 {
89 SF_LOG_FATAL("misc", "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in world!!", GetGUID(), uint8(GetTypeId()), GetEntry());
91 SF_LOG_FATAL("misc", "Item slot %u", ((Item*)this)->GetSlot());
92 ASSERT(false);
94 }
95
97 {
98 SF_LOG_FATAL("misc", "Object::~Object - guid=" UI64FMTD ", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), uint8(GetTypeId()), GetEntry());
99 ASSERT(false);
100 sObjectAccessor->RemoveUpdateObject(this);
101 }
102
103 delete[] m_uint32Values;
104 m_uint32Values = 0;
105
106 for (size_t i = 0; i < m_dynamicTab.size(); ++i)
107 {
108 delete[] m_dynamicTab[i];
109 delete[] m_dynamicChange[i];
110 }
111}
112
114{
116 memset(m_uint32Values, 0, m_valuesCount * sizeof(uint32));
117
118 _changesMask.SetCount(m_valuesCount);
119
120 for (size_t i = 0; i < m_dynamicTab.size(); ++i)
121 {
122 memset(m_dynamicTab[i], 0, 32 * sizeof(uint32));
123 memset(m_dynamicChange[i], 0, 32 * sizeof(bool));
124 }
125
126 m_objectUpdated = false;
127}
128
129void Object::_Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
130{
132
133 uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh);
136 m_PackGUID.clear();
137 m_PackGUID.appendPackGUID(GetGUID());
138}
139
140std::string Object::_ConcatFields(uint16 startIndex, uint16 size) const
141{
142 std::ostringstream ss;
143 for (uint16 index = 0; index < size; ++index)
144 ss << GetUInt32Value(index + startIndex) << ' ';
145 return ss.str();
146}
147
149{
150 if (m_inWorld)
151 return;
152
154
155 m_inWorld = true;
156
157 // synchronize values mirror with values array (changes will send in updatecreate opcode any way
158 ClearUpdateMask(true);
159}
160
162{
163 if (!m_inWorld)
164 return;
165
166 m_inWorld = false;
167
168 // if we remove from world then sending changes not required
169 ClearUpdateMask(true);
170}
171
173{
174 if (!target)
175 return;
176
177 uint8 updateType = UPDATETYPE_CREATE_OBJECT;
178 uint16 flags = m_updateFlag;
179
181 if (target == this) // building packet for yourself
182 flags |= UPDATEFLAG_SELF;
183
184 switch (GetGUIDHigh())
185 {
186 case HIGHGUID_PLAYER:
187 case HIGHGUID_PET:
188 case HIGHGUID_CORPSE:
191 updateType = UPDATETYPE_CREATE_OBJECT2;
192 break;
193 case HIGHGUID_UNIT:
194 case HIGHGUID_VEHICLE:
195 {
196 if (TempSummon const* summon = ToUnit()->ToTempSummon())
197 if (IS_PLAYER_GUID(summon->GetSummonerGUID()))
198 updateType = UPDATETYPE_CREATE_OBJECT2;
199
200 break;
201 }
203 {
204 // SPELL_FOCUS GOs (e.g. Basic Campfire 29784) crash the 5.4.8 client when
205 // sent as CREATE_OBJECT2 with a player CREATED_BY (WowClientDB2 OOM).
206 if (IS_PLAYER_GUID(ToGameObject()->GetOwnerGUID()) &&
208 updateType = UPDATETYPE_CREATE_OBJECT2;
209 break;
210 }
211 default:
212 break;
213 }
214
216 {
217 // UPDATETYPE_CREATE_OBJECT2 for some gameobject types...
219 {
220 switch (ToGameObject()->GetGoType())
221 {
226 updateType = UPDATETYPE_CREATE_OBJECT2;
227 break;
228 default:
229 break;
230 }
231 }
232 }
233
234 // MoP 5.4.8 client: SPELL_FOCUS GOs must use CREATE_OBJECT (WowClientDB2 OOM otherwise).
236 {
237 GameobjectTypes const goType = ToGameObject()->GetGoType();
238 if (goType == GAMEOBJECT_TYPE_SPELL_FOCUS)
239 updateType = UPDATETYPE_CREATE_OBJECT;
240 // Linked campfire trap (31442): CREATE_OBJECT2 on environmental traps also crashes client.
241 else if (goType == GAMEOBJECT_TYPE_TRAP && !ToGameObject()->GetOwnerGUID())
242 updateType = UPDATETYPE_CREATE_OBJECT;
243 }
244
245 if (Unit const* unit = ToUnit())
246 if (unit->GetVictim())
247 flags |= UPDATEFLAG_HAS_TARGET;
248
249 ByteBuffer buf(500);
250 buf << uint8(updateType);
251 buf.append(GetPackGUID());
252 buf << uint8(m_objectTypeId);
253
254 BuildMovementUpdate(&buf, flags);
255 BuildValuesUpdate(updateType, &buf, target);
256 data->AddUpdateBlock(buf);
257}
258
260{
261 // send create update to player
262 UpdateData upd(player->GetMapId());
263 WorldPacket packet;
264
266 upd.BuildPacket(&packet);
267 player->GetSession()->SendPacket(&packet);
268}
269
271{
272 ByteBuffer buf(500);
273
274 buf << uint8(UPDATETYPE_VALUES);
275 buf.append(GetPackGUID());
276
278
279 data->AddUpdateBlock(buf);
280}
281
286
287void Object::DestroyForPlayer(Player* target, bool onDeath) const
288{
289 ASSERT(target);
290
292 {
293 if (Battleground* bg = target->GetBattleground())
294 {
295 if (bg->isArena())
296 {
298 data << uint64(GetGUID());
299 target->GetSession()->SendPacket(&data);
300 }
301 }
302 }
303 SendDestroyObject(target, GetObjectGUID(), onDeath);
304}
305
306void Object::SendDestroyObject(Player* target, ObjectGuid Guid, bool onDeath) const
307{
308 WorldPacket data(SMSG_DESTROY_OBJECT, 1 + 8);
309 data.WriteGuidMask(Guid, 3, 2, 4, 1);
312 data.WriteBit(onDeath);
313 data.WriteGuidMask(Guid, 7, 0, 6, 5);
314 data.FlushBits();
315 data.WriteGuidBytes(Guid, 0, 4, 7, 2, 6, 3, 1, 5);
316 target->GetSession()->SendPacket(&data);
317}
318
320{
321 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
322 return m_int32Values[index];
323}
324
326{
327 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
328 return m_uint32Values[index];
329}
330
332{
333 ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, false));
334 return *((uint64*)&(m_uint32Values[index]));
335}
336
338{
339 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
340 return m_floatValues[index];
341}
342
344{
345 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
346 ASSERT(offset < 4);
347 return *(((uint8*)&m_uint32Values[index]) + offset);
348}
349
351{
352 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
353 ASSERT(offset < 2);
354 return *(((uint16*)&m_uint32Values[index]) + offset);
355}
356
358{
359 ASSERT(tab < m_dynamicTab.size() && index < 32);
360 return m_dynamicTab[tab][index];
361}
362
364{
365 bool hasFallData = false;
366 bool hasFallDirection = false;
367 bool hasSpline = false;
368 bool hasPitch = false;
369 bool hasSplineElevation = false;
370 bool hasUnitTransport = false;
371
372 uint32 movementFlags;
373 uint32 movementFlagsExtra;
374 std::vector<uint32> const* pauseTimes = NULL;
375
376 if (GameObject const* go = ToGameObject())
377 pauseTimes = go->GetPauseTimes();
378
379 data->WriteBit(0); // 676 UPDATEFLAG_HAS_GAMEOBJECT // NEW
380 data->WriteBit(false /*flags & UPDATEFLAG_ANIMKITS*/); // 498 UPDATEFLAG_ANIMKITS // OLD
381 data->WriteBit(flags & UPDATEFLAG_LIVING); // 368 UPDATEFLAG_LIVING // OLD
382 data->WriteBit(0); // 810 UPDATEFLAG_SCENE_LOCAL_SCRIPT_DATA // NEW
383 data->WriteBit(0);
384 data->WriteBits(pauseTimes ? pauseTimes->size() : 0, 22); // 1068 UPDATEFLAG_TRANSPORT_FRAME_COUNT // NEW
385 data->WriteBit(flags & UPDATEFLAG_VEHICLE); // 488 UPDATEFLAG_VEHICLE // OLD
386 data->WriteBit(0); // 1044 UNK
387 data->WriteBit(0);
388 data->WriteBit(flags & UPDATEFLAG_TRANSPORT); // 476 UPDATEFLAG_TRANSPORT // OLD
389 data->WriteBit(flags & UPDATEFLAG_ROTATION); // 512 UPDATEFLAG_ROTATION // OLD
390 data->WriteBit(0);
391 data->WriteBit(flags & UPDATEFLAG_SELF); // 680 UPDATEFLAG_SELF // OLD
392 data->WriteBit(flags & UPDATEFLAG_HAS_TARGET); // 464 UPDATEFLAG_HAS_TARGET // OLD
393 data->WriteBit(0); // 1032 UPDATEFLAG_SCENE_OBJECT // NEW
394 data->WriteBit(0); // 1064 UPDATEFLAG_SCENE_PENDING_INSTANCES // NEW
395 data->WriteBit(0);
396 data->WriteBit(0); // 668 UPDATEFLAG_HAS_AREATRIGGER // NEW
397 data->WriteBit(flags & UPDATEFLAG_GO_TRANSPORT_POSITION); // 424 UPDATEFLAG_GO_TRANSPORT_POSITION // OLD
398 data->WriteBit(0); // 681 UPDATEFLAG_REPLACE_YOU // NEW
399 data->WriteBit(flags & UPDATEFLAG_STATIONARY_POSITION); // 448 UPDATEFLAG_STATIONARY_POSITION // OLD
400
401 if (flags & UPDATEFLAG_LIVING) // 368
402 {
403 Unit const* self = ToUnit();
404 ObjectGuid guid = GetGUID();
405
406 hasFallDirection = self->HasUnitMovementFlag(MOVEMENTFLAG_FALLING);
407 hasFallData = hasFallDirection || self->m_movementInfo.jump.fallTime != 0;
408 movementFlags = self->GetUnitMovementFlags();
409 movementFlagsExtra = self->GetExtraUnitMovementFlags();
410 hasSpline = self->IsSplineEnabled() && self->GetTypeId() != TypeID::TYPEID_PLAYER;
412 hasSplineElevation = self->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
413 hasUnitTransport = self->m_movementInfo.transport.guid;
414
416 movementFlags &= MOVEMENTFLAG_MASK_CREATURE_ALLOWED;
417
418 data->WriteBit(guid[2]);
419 data->WriteBit(0);
420 data->WriteBit(!hasPitch);
421 data->WriteBit(hasUnitTransport);
422 data->WriteBit(0);
423
424 if (hasUnitTransport)
425 {
426 ObjectGuid transGuid = self->m_movementInfo.transport.guid;
427 data->WriteBit(transGuid[4]);
428 data->WriteBit(transGuid[2]);
430 data->WriteBit(transGuid[0]);
431 data->WriteBit(transGuid[1]);
432 data->WriteBit(transGuid[3]);
433 data->WriteBit(transGuid[6]);
434 data->WriteBit(transGuid[7]);
436 data->WriteBit(transGuid[5]);
437 }
438
439 data->WriteBit(!self->m_movementInfo.time);
440 data->WriteBit(guid[6]);
441 data->WriteBit(guid[4]);
442 data->WriteBit(guid[3]);
443
444 data->WriteBit(G3D::fuzzyEq(self->GetOrientation(), 0.0f));
445
446 data->WriteBit(!self->GetMovementCounter());
447 data->WriteBit(guid[5]);
448 data->WriteBits(0, 22); // Forces
449 data->WriteBit(!movementFlags);
450 data->WriteBits(0, 19);
451 data->WriteBit(hasFallData);
452
453 if (movementFlags)
454 data->WriteBits(movementFlags, 30);
455
456 data->WriteBit(!hasSplineElevation);
457 data->WriteBit(hasSpline);
458 data->WriteBit(0);
459 data->WriteBit(guid[0]);
460 data->WriteBit(guid[7]);
461 data->WriteBit(guid[1]);
462
463 if (hasSpline)
465
466 data->WriteBit(!movementFlagsExtra);
467
468 if (hasFallData)
469 data->WriteBit(hasFallDirection);
470
471 if (movementFlagsExtra)
472 data->WriteBits(movementFlagsExtra, 13);
473 }
474
475 // 1032 {}
476
477 if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION) // 424
478 {
479 WorldObject const* self = static_cast<WorldObject const*>(this);
480 ObjectGuid transGuid = self->m_movementInfo.transport.guid;
481 data->WriteBit(transGuid[4]);
482 data->WriteBit(transGuid[1]);
483 data->WriteBit(transGuid[0]);
485 data->WriteBit(transGuid[6]);
486 data->WriteBit(transGuid[5]);
487 data->WriteBit(transGuid[3]);
488 data->WriteBit(transGuid[2]);
489 data->WriteBit(transGuid[7]);
491 }
492
493 /*
494 if (flags & UPDATEFLAG_HAS_AREATRIGGER) // 668
495 {
496 data->WriteBit(0); // 528
497 data->WriteBit(0); // 600
498 data->WriteBit(0); // 544
499 data->WriteBit(0); // 526
500 data->WriteBit(0); // 552
501 data->WriteBit(0); // 524
502 data->WriteBit(0); // 572
503 data->WriteBit(0); // 525
504 data->WriteBit(0); // 664 has664
505 data->WriteBit(0); // 527
506
507 if (664) // 664
508 data->WriteBits(0, 20); // v70
509
510 data->WriteBit(0); // 536
511 data->WriteBit(0); // 644 has644
512 data->WriteBit(0); // 560
513
514 if (644) // 644
515 {
516 //v4 = sub_6652D0(v7, v6) << (13 - v3);
517 //v3 += 8;
518 //v2 |= v4;
519 data->WriteBits(0, 21); // v71 // 151
520 data->WriteBits(0, 21); // v72 // 155
521 }
522 }
523 */
524
525 /*
526 if (flags & UPDATEFLAG_ANIMKITS) // 498
527 {
528 data->WriteBit(1); // Missing AnimKit1
529 data->WriteBit(1); // Missing AnimKit2
530 data->WriteBit(1); // Missing AnimKit3
531 }
532 */
533
534 if (flags & UPDATEFLAG_HAS_TARGET) // 464
535 {
536 Unit const* self = ToUnit();
537 ObjectGuid victimGuid = self->GetVictim()->GetGUID();
538 data->WriteBit(victimGuid[4]);
539 data->WriteBit(victimGuid[6]);
540 data->WriteBit(victimGuid[5]);
541 data->WriteBit(victimGuid[2]);
542 data->WriteBit(victimGuid[0]);
543 data->WriteBit(victimGuid[1]);
544 data->WriteBit(victimGuid[3]);
545 data->WriteBit(victimGuid[7]);
546 }
547
548 // 1064 {}
549 // 810 {}
550
551 data->FlushBits();
552
553 // 1068 {}
554 if (pauseTimes && !pauseTimes->empty())
555 data->append(pauseTimes->data(), pauseTimes->size());
556
557 // 1032 {}
558
559 if (flags & UPDATEFLAG_LIVING)
560 {
561 Unit const* self = ToUnit();
562 ObjectGuid guid = GetGUID();
563
564 if (hasUnitTransport)
565 {
566 ObjectGuid transGuid = self->m_movementInfo.transport.guid;
567
568 data->WriteByteSeq(transGuid[7]);
569 *data << float(self->GetTransOffsetX());
570
572 *data << uint32(self->m_movementInfo.transport.time3);
573
574 *data << float(self->GetTransOffsetO());
575 *data << float(self->GetTransOffsetY());
576 data->WriteByteSeq(transGuid[4]);
577 data->WriteByteSeq(transGuid[1]);
578 data->WriteByteSeq(transGuid[3]);
579 *data << float(self->GetTransOffsetZ());
580 data->WriteByteSeq(transGuid[5]);
581
583 *data << uint32(self->m_movementInfo.transport.time2);
584
585 data->WriteByteSeq(transGuid[0]);
586 *data << int8(self->GetTransSeat());
587 data->WriteByteSeq(transGuid[6]);
588 data->WriteByteSeq(transGuid[2]);
589 *data << uint32(self->GetTransTime());
590 }
591
592 data->WriteByteSeq(guid[4]);
593
594 if (hasSpline)
596
597 *data << float(self->GetSpeed(MOVE_FLIGHT));
598
599 if (self->GetMovementCounter())
600 *data << uint32(self->GetMovementCounter());
601
602 data->WriteByteSeq(guid[2]);
603
604 if (hasFallData)
605 {
606 if (hasFallDirection)
607 {
608 *data << float(self->m_movementInfo.jump.xyspeed);
609 *data << float(self->m_movementInfo.jump.cosAngle);
610 *data << float(self->m_movementInfo.jump.sinAngle);
611 }
612
613 *data << uint32(self->m_movementInfo.jump.fallTime);
614 *data << float(self->m_movementInfo.jump.zspeed);
615 }
616
617 data->WriteByteSeq(guid[1]);
618 *data << float(self->GetSpeed(MOVE_TURN_RATE));
619
620 if (self->m_movementInfo.time)
621 *data << uint32(self->m_movementInfo.time);
622
623 *data << float(self->GetSpeed(MOVE_RUN_BACK));
624
625 if (hasSplineElevation)
626 *data << float(self->m_movementInfo.splineElevation);
627
628 data->WriteByteSeq(guid[7]);
629 *data << float(self->GetSpeed(MOVE_PITCH_RATE));
630 *data << float(self->GetPositionX());
631
632 if (hasPitch)
633 *data << float(self->m_movementInfo.pitch);
634
635 if (!G3D::fuzzyEq(self->GetOrientation(), 0.0f))
636 *data << float(Position::NormalizeOrientation(self->GetOrientation()));
637
638 *data << float(self->GetSpeed(MOVE_WALK));
639 *data << float(self->GetPositionY());
640 *data << float(self->GetSpeed(MOVE_FLIGHT_BACK));
641 data->WriteByteSeq(guid[3]);
642 data->WriteByteSeq(guid[5]);
643 data->WriteByteSeq(guid[6]);
644 data->WriteByteSeq(guid[0]);
645 *data << float(self->GetSpeed(MOVE_SWIM_BACK));
646 *data << float(self->GetSpeed(MOVE_RUN));
647 *data << float(self->GetSpeed(MOVE_SWIM));
648 *data << float(self->GetPositionZMinusOffset());
649 }
650
652 {
653 WorldObject const* self = static_cast<WorldObject const*>(this);
654 ObjectGuid transGuid = self->m_movementInfo.transport.guid;
655
657 *data << uint32(self->m_movementInfo.transport.time2);
658
659 *data << float(self->GetTransOffsetY());
660 *data << int8(self->GetTransSeat());
661 *data << float(self->GetTransOffsetX());
662 data->WriteBit(transGuid[2]);
663 data->WriteBit(transGuid[4]);
664 data->WriteBit(transGuid[1]);
665
667 *data << uint32(self->m_movementInfo.transport.time3);
668
669 *data << uint32(self->GetTransTime());
670
671 *data << float(self->GetTransOffsetO());
672 *data << float(self->GetTransOffsetZ());
673
674 data->WriteBit(transGuid[6]);
675 data->WriteBit(transGuid[0]);
676 data->WriteBit(transGuid[5]);
677 data->WriteBit(transGuid[3]);
678 data->WriteBit(transGuid[7]);
679 }
680
681 /*
682 if (flags & UPDATEFLAG_HAS_AREATRIGGER) // 668
683 {
684 if (664)
685 {
686 //forloop12 162
687 *data << float(0.0f); //v107 // 4
688 *data << float(0.0f); //v108 // 0
689 *data << float(0.0f); //v109 // 8
690 }
691 if (600)
692 {
693 *data << float(0.0f); // 146
694 *data << float(0.0f); // 145
695 *data << float(0.0f); // 149
696 *data << float(0.0f); // 148
697 *data << float(0.0f); // 144
698 *data << float(0.0f); // 147
699 }
700 if (644)
701 {
702 if(151)
703 {
704 //forloop 151
705 *data << float(0.0f); //v110 // 0 // 152
706 *data << float(0.0f); //v111 // 4 // 152
707 }
708
709 if (155)
710 {
711 //forloop 155
712 *data << float(0.0f); //v112 // 0 // 156
713 *data << float(0.0f); //v113 // 4 // 156
714 }
715
716 *data << float(0.0f); // 160
717 *data << float(0.0f); // 159
718 }
719 *data << uint32(0); //130
720
721 if (544)
722 *data << uint32(0); //135
723
724 if (552)
725 *data << uint32(0); //137
726
727 if (536)
728 *data << uint32(0); //133
729
730 if (560)
731 *data << uint32(0); //139
732
733 if (572)
734 {
735 *data << float(0.0f); // 141
736 *data << float(0.0f); // 142
737 }
738 }
739 */
740
741 if (flags & UPDATEFLAG_HAS_TARGET) // 464
742 {
743 Unit const* self = ToUnit();
744 ObjectGuid victimGuid = self->GetVictim()->GetGUID();
745 data->WriteByteSeq(victimGuid[7]);
746 data->WriteByteSeq(victimGuid[1]);
747 data->WriteByteSeq(victimGuid[5]);
748 data->WriteByteSeq(victimGuid[2]);
749 data->WriteByteSeq(victimGuid[6]);
750 data->WriteByteSeq(victimGuid[3]);
751 data->WriteByteSeq(victimGuid[0]);
752 data->WriteByteSeq(victimGuid[4]);
753 }
754
755 if (flags & UPDATEFLAG_VEHICLE)
756 {
757 Unit const* self = ToUnit();
758 *data << uint32(self->GetVehicleKit()->GetVehicleInfo()->m_ID);
759 *data << float(self->GetOrientation());
760 }
761
763 {
764 WorldObject const* self = static_cast<WorldObject const*>(this);
765 *data << float(self->GetStationaryY());
766 if (Unit const* unit = ToUnit())
767 *data << float(unit->GetPositionZMinusOffset());
768 else
769 *data << float(self->GetStationaryZ());
770 *data << float(Position::NormalizeOrientation(self->GetStationaryO()));
771 *data << float(self->GetStationaryX());
772 }
773
774 // 676 {}
775 /*
776 if (flags & UPDATEFLAG_ANIMKITS)
777 {
778 if (hasAnimKit3)
779 *data << uint16(animKit3);
780 if (hasAnimKit2)
781 *data << uint16(animKit2);
782 if (hasAnimKit1)
783 *data << uint16(animKit1);
784 }*/
785
786 // 810 {}
787 if (flags & UPDATEFLAG_TRANSPORT)
788 {
789 GameObject const* go = ToGameObject();
790
791 if (go && (go->ToTransport() || go->GetGoType() == GAMEOBJECT_TYPE_TRANSPORT))
792 *data << uint32(go->GetGOValue()->Transport.PathProgress);
793 else
794 *data << uint32(getMSTime());
795 }
796 // 1064 {}
797 if (flags & UPDATEFLAG_ROTATION)
798 *data << uint64(ToGameObject()->GetRotation());
799 // 1044 {}
800 if (flags & UPDATEFLAG_LIVING && hasSpline)
802}
803
804void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
805{
806 if (!target)
807 return;
808
809 ByteBuffer fieldBuffer;
810 UpdateMask updateMask;
811 updateMask.SetCount(m_valuesCount);
812
813 uint32* flags = NULL;
814 uint32 visibleFlag = GetUpdateFieldData(target, flags);
815
816 for (uint16 index = 0; index < m_valuesCount; ++index)
817 {
818 if ((m_fieldNotifyFlags & flags[index] ||
819 ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag))))
820 {
821 updateMask.SetBit(index);
822 fieldBuffer << m_uint32Values[index];
823 }
824 }
825
826 *data << uint8(updateMask.GetBlockCount());
827 updateMask.AppendToPacket(data);
828 data->append(fieldBuffer);
829 BuildDynamicValuesUpdate(updateType, data, target);
830}
831
832void Object::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
833{
834 // Items use dynamic modifiers; players use archaeology digsite / daily-quest dynamic fields.
836 {
837 *data << uint8(0);
838 return;
839 }
840
841 // Player dynamic fields are private (self only).
842 if (m_objectTypeId == TypeID::TYPEID_PLAYER && target != this)
843 {
844 *data << uint8(0);
845 return;
846 }
847
848 bool const isCreate = updateType == UPDATETYPE_CREATE_OBJECT || updateType == UPDATETYPE_CREATE_OBJECT2;
849
850 // Dynamic Fields (5.0.5 MoP new fields)
851 uint32 dynamicTabMask = 0;
852 std::vector<uint32> dynamicFieldsMask;
853 dynamicFieldsMask.resize(m_dynamicTab.size());
854
855 for (size_t i = 0; i < m_dynamicTab.size(); i++)
856 dynamicFieldsMask[i] = 0;
857
858 for (size_t i = 0; i < m_dynamicChange.size(); i++)
859 {
860 for (int index = 0; index < 32; index++)
861 {
862 bool sendValue = isCreate ? m_dynamicTab[i][index] != 0 : m_dynamicChange[i][index];
863
864 // Client expects researchSiteProgress entries for every active researchSites index,
865 // including zero progress on a fresh digsite.
866 if (!sendValue && isCreate && m_objectTypeId == TypeID::TYPEID_PLAYER &&
870 sendValue = true;
871
872 if (sendValue)
873 {
874 dynamicTabMask |= 1 << i;
875 dynamicFieldsMask[i] |= 1 << index;
876 }
877 }
878 }
879
880 *data << uint8(bool(dynamicTabMask) ? 1 : 0);
881 if (dynamicTabMask)
882 {
883 *data << uint32(dynamicTabMask);
884
885 for (size_t i = 0; i < m_dynamicTab.size(); i++)
886 {
887 if (dynamicTabMask & (1 << i))
888 {
889 uint16 arraySize = 0;
890 for (int index = 31; index >= 0; --index)
891 {
892 if (dynamicFieldsMask[i] & (1 << index))
893 {
894 arraySize = uint16(index + 1);
895 break;
896 }
897 }
898
899 // MoP: high bit on the count byte means a uint16 array size follows.
900 if (isCreate && arraySize)
901 *data << uint8(0x80 | 1) << arraySize;
902 else
903 *data << uint8(1);
904
905 *data << uint32(dynamicFieldsMask[i]);
906
907 for (int index = 0; index < 32; index++)
908 {
909 if (dynamicFieldsMask[i] & (1 << index))
910 *data << uint32(m_dynamicTab[i][index]);
911 }
912 }
913 }
914 }
915}
916
917void Object::ClearUpdateMask(bool remove)
918{
919 _changesMask.Clear();
920
921 if (m_objectUpdated)
922 {
923 for (size_t i = 0; i < m_dynamicTab.size(); i++)
924 memset(m_dynamicChange[i], 0, 32 * sizeof(bool));
925
926 if (remove)
927 sObjectAccessor->RemoveUpdateObject(this);
928 m_objectUpdated = false;
929 }
930}
931
933{
934 UpdateDataMapType::iterator iter = data_map.find(player);
935
936 if (iter == data_map.end())
937 {
938 std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData(player->GetMapId())));
939 ASSERT(p.second);
940 iter = p.first;
941 }
942
943 BuildValuesUpdateBlockForPlayer(&iter->second, iter->first);
944}
945
946uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const
947{
949
950 if (target == this)
951 visibleFlag |= UF_FLAG_PRIVATE;
952
953 switch (GetTypeId())
954 {
957 flags = ItemUpdateFieldFlags;
958 if (((Item*)this)->GetOwnerGUID() == target->GetGUID())
959 visibleFlag |= UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER;
960 break;
963 {
965 flags = UnitUpdateFieldFlags;
966 if (ToUnit()->GetOwnerGUID() == target->GetGUID())
967 visibleFlag |= UF_FLAG_OWNER;
968
970 if (ToUnit()->HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID()))
971 visibleFlag |= UF_FLAG_SPECIAL_INFO;
972
973 if (plr && plr->IsInSameRaidWith(target))
974 visibleFlag |= UF_FLAG_PARTY_MEMBER;
975 break;
976 }
979 if (ToGameObject()->GetOwnerGUID() == target->GetGUID())
980 visibleFlag |= UF_FLAG_OWNER;
981 break;
984 if (((DynamicObject*)this)->GetCasterGUID() == target->GetGUID())
985 visibleFlag |= UF_FLAG_OWNER;
986 break;
989 if (ToCorpse()->GetOwnerGUID() == target->GetGUID())
990 visibleFlag |= UF_FLAG_OWNER;
991 break;
994 break;
996 break;
997 default:
998 break;
999 }
1000
1001 return visibleFlag;
1002}
1003
1004void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count)
1005{
1006 if (data.empty())
1007 return;
1008
1009 Tokenizer tokens(data, ' ', count);
1010
1011 if (tokens.size() != count)
1012 return;
1013
1014 for (uint32 index = 0; index < count; ++index)
1015 {
1016 m_uint32Values[startOffset + index] = atol(tokens[index]);
1017 _changesMask.SetBit(startOffset + index);
1018 }
1019}
1020
1022{
1023 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1024
1025 if (m_int32Values[index] != value)
1026 {
1027 m_int32Values[index] = value;
1028 _changesMask.SetBit(index);
1029
1030 if (m_inWorld && !m_objectUpdated)
1031 {
1032 sObjectAccessor->AddUpdateObject(this);
1033 m_objectUpdated = true;
1034 }
1035 }
1036}
1037
1039{
1040 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1041
1042 if (m_uint32Values[index] != value)
1043 {
1044 m_uint32Values[index] = value;
1045 _changesMask.SetBit(index);
1046
1047 if (m_inWorld && !m_objectUpdated)
1048 {
1049 sObjectAccessor->AddUpdateObject(this);
1050 m_objectUpdated = true;
1051 }
1052 }
1053}
1054
1056{
1057 ASSERT(tab < m_dynamicTab.size() && index < 32);
1058
1059 if (m_dynamicTab[tab][index] != value)
1060 {
1061 m_dynamicTab[tab][index] = value;
1062 m_dynamicChange[tab][index] = true;
1063 if (m_inWorld && !m_objectUpdated)
1064 {
1065 sObjectAccessor->AddUpdateObject(this);
1066 m_objectUpdated = true;
1067 }
1068 }
1069}
1070
1072{
1073 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1074
1075 m_uint32Values[index] = value;
1076 _changesMask.SetBit(index);
1077}
1078
1080{
1081 ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
1082 if (*((uint64*)&(m_uint32Values[index])) != value)
1083 {
1084 m_uint32Values[index] = PAIR64_LOPART(value);
1085 m_uint32Values[index + 1] = PAIR64_HIPART(value);
1086 _changesMask.SetBit(index);
1087 _changesMask.SetBit(index + 1);
1088
1089 if (m_inWorld && !m_objectUpdated)
1090 {
1091 sObjectAccessor->AddUpdateObject(this);
1092 m_objectUpdated = true;
1093 }
1094 }
1095}
1096
1098{
1099 ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
1100 if (value && !*((uint64*)&(m_uint32Values[index])))
1101 {
1102 m_uint32Values[index] = PAIR64_LOPART(value);
1103 m_uint32Values[index + 1] = PAIR64_HIPART(value);
1104 _changesMask.SetBit(index);
1105 _changesMask.SetBit(index + 1);
1106
1107 if (m_inWorld && !m_objectUpdated)
1108 {
1109 sObjectAccessor->AddUpdateObject(this);
1110 m_objectUpdated = true;
1111 }
1112
1113 return true;
1114 }
1115
1116 return false;
1117}
1118
1120{
1121 ASSERT(index + 1 < m_valuesCount || PrintIndexError(index, true));
1122 if (value && *((uint64*)&(m_uint32Values[index])) == value)
1123 {
1124 m_uint32Values[index] = 0;
1125 m_uint32Values[index + 1] = 0;
1126 _changesMask.SetBit(index);
1127 _changesMask.SetBit(index + 1);
1128
1129 if (m_inWorld && !m_objectUpdated)
1130 {
1131 sObjectAccessor->AddUpdateObject(this);
1132 m_objectUpdated = true;
1133 }
1134
1135 return true;
1136 }
1137
1138 return false;
1139}
1140
1141void Object::SetFloatValue(uint16 index, float value)
1142{
1143 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1144
1145 if (m_floatValues[index] != value)
1146 {
1147 m_floatValues[index] = value;
1148 _changesMask.SetBit(index);
1149
1150 if (m_inWorld && !m_objectUpdated)
1151 {
1152 sObjectAccessor->AddUpdateObject(this);
1153 m_objectUpdated = true;
1154 }
1155 }
1156}
1157
1158void Object::SetByteValue(uint16 index, uint8 offset, uint8 value)
1159{
1160 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1161
1162 if (offset > 4)
1163 {
1164 SF_LOG_ERROR("misc", "Object::SetByteValue: wrong offset %u", offset);
1165 return;
1166 }
1167
1168 if (uint8(m_uint32Values[index] >> (offset * 8)) != value)
1169 {
1170 m_uint32Values[index] &= ~uint32(uint32(0xFF) << (offset * 8));
1171 m_uint32Values[index] |= uint32(uint32(value) << (offset * 8));
1172 _changesMask.SetBit(index);
1173
1174 if (m_inWorld && !m_objectUpdated)
1175 {
1176 sObjectAccessor->AddUpdateObject(this);
1177 m_objectUpdated = true;
1178 }
1179 }
1180}
1181
1182void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value)
1183{
1184 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1185
1186 if (offset > 2)
1187 {
1188 SF_LOG_ERROR("misc", "Object::SetUInt16Value: wrong offset %u", offset);
1189 return;
1190 }
1191
1192 if (uint16(m_uint32Values[index] >> (offset * 16)) != value)
1193 {
1194 m_uint32Values[index] &= ~uint32(uint32(0xFFFF) << (offset * 16));
1195 m_uint32Values[index] |= uint32(uint32(value) << (offset * 16));
1196 _changesMask.SetBit(index);
1197
1198 if (m_inWorld && !m_objectUpdated)
1199 {
1200 sObjectAccessor->AddUpdateObject(this);
1201 m_objectUpdated = true;
1202 }
1203 }
1204}
1205
1206void Object::SetStatFloatValue(uint16 index, float value)
1207{
1208 if (value < 0)
1209 value = 0.0f;
1210
1211 SetFloatValue(index, value);
1212}
1213
1215{
1216 if (value < 0)
1217 value = 0;
1218
1219 SetUInt32Value(index, uint32(value));
1220}
1221
1222void Object::ApplyModUInt32Value(uint16 index, int32 val, bool apply)
1223{
1224 int32 cur = GetUInt32Value(index);
1225 cur += (apply ? val : -val);
1226 if (cur < 0)
1227 cur = 0;
1228 SetUInt32Value(index, cur);
1229}
1230
1231void Object::ApplyModInt32Value(uint16 index, int32 val, bool apply)
1232{
1233 int32 cur = GetInt32Value(index);
1234 cur += (apply ? val : -val);
1235 SetInt32Value(index, cur);
1236}
1237
1238void Object::ApplyModSignedFloatValue(uint16 index, float val, bool apply)
1239{
1240 float cur = GetFloatValue(index);
1241 cur += (apply ? val : -val);
1242 SetFloatValue(index, cur);
1243}
1244
1245void Object::ApplyPercentModFloatValue(uint16 index, float val, bool apply)
1246{
1247 float value = GetFloatValue(index);
1248 ApplyPercentModFloatVar(value, val, apply);
1249 SetFloatValue(index, value);
1250}
1251
1252void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
1253{
1254 float cur = GetFloatValue(index);
1255 cur += (apply ? val : -val);
1256 if (cur < 0)
1257 cur = 0;
1258 SetFloatValue(index, cur);
1259}
1260
1261void Object::SetFlag(uint16 index, uint32 newFlag)
1262{
1263 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1264 uint32 oldval = m_uint32Values[index];
1265 uint32 newval = oldval | newFlag;
1266
1267 if (oldval != newval)
1268 {
1269 m_uint32Values[index] = newval;
1270 _changesMask.SetBit(index);
1271
1272 if (m_inWorld && !m_objectUpdated)
1273 {
1274 sObjectAccessor->AddUpdateObject(this);
1275 m_objectUpdated = true;
1276 }
1277 }
1278}
1279
1281{
1282 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1284
1285 uint32 oldval = m_uint32Values[index];
1286 uint32 newval = oldval & ~oldFlag;
1287
1288 if (oldval != newval)
1289 {
1290 m_uint32Values[index] = newval;
1291 _changesMask.SetBit(index);
1292
1293 if (m_inWorld && !m_objectUpdated)
1294 {
1295 sObjectAccessor->AddUpdateObject(this);
1296 m_objectUpdated = true;
1297 }
1298 }
1299}
1300
1302{
1303 if (HasFlag(index, flag))
1304 RemoveFlag(index, flag);
1305 else
1306 SetFlag(index, flag);
1307}
1308
1309bool Object::HasFlag(uint16 index, uint32 flag) const
1310{
1311 if (index >= m_valuesCount && !PrintIndexError(index, false))
1312 return false;
1313
1314 return (m_uint32Values[index] & flag) != 0;
1315}
1316
1317void Object::ApplyModFlag(uint16 index, uint32 flag, bool apply)
1318{
1319 if (apply) SetFlag(index, flag); else RemoveFlag(index, flag);
1320}
1321
1322void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
1323{
1324 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1325
1326 if (offset > 4)
1327 {
1328 SF_LOG_ERROR("misc", "Object::SetByteFlag: wrong offset %u", offset);
1329 return;
1330 }
1331
1332 if (!(uint8(m_uint32Values[index] >> (offset * 8)) & newFlag))
1333 {
1334 m_uint32Values[index] |= uint32(uint32(newFlag) << (offset * 8));
1335 _changesMask.SetBit(index);
1336
1337 if (m_inWorld && !m_objectUpdated)
1338 {
1339 sObjectAccessor->AddUpdateObject(this);
1340 m_objectUpdated = true;
1341 }
1342 }
1343}
1344
1345void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag)
1346{
1347 ASSERT(index < m_valuesCount || PrintIndexError(index, true));
1348
1349 if (offset > 4)
1350 {
1351 SF_LOG_ERROR("misc", "Object::RemoveByteFlag: wrong offset %u", offset);
1352 return;
1353 }
1354
1355 if (uint8(m_uint32Values[index] >> (offset * 8)) & oldFlag)
1356 {
1357 m_uint32Values[index] &= ~uint32(uint32(oldFlag) << (offset * 8));
1358 _changesMask.SetBit(index);
1359
1360 if (m_inWorld && !m_objectUpdated)
1361 {
1362 sObjectAccessor->AddUpdateObject(this);
1363 m_objectUpdated = true;
1364 }
1365 }
1366}
1367
1368void Object::ToggleByteFlag(uint16 index, uint8 offset, uint8 flag)
1369{
1370 if (HasByteFlag(index, offset, flag))
1371 RemoveByteFlag(index, offset, flag);
1372 else
1373 SetByteFlag(index, offset, flag);
1374}
1375
1376bool Object::HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
1377{
1378 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
1379 ASSERT(offset < 4);
1380 return (((uint8*)&m_uint32Values[index])[offset] & flag) != 0;
1381}
1382
1383void Object::SetFlag64(uint16 index, uint64 newFlag)
1384{
1385 uint64 oldval = GetUInt64Value(index);
1386 uint64 newval = oldval | newFlag;
1387 SetUInt64Value(index, newval);
1388}
1389
1391{
1392 uint64 oldval = GetUInt64Value(index);
1393 uint64 newval = oldval & ~oldFlag;
1394 SetUInt64Value(index, newval);
1395}
1396
1398{
1399 if (HasFlag64(index, flag))
1400 RemoveFlag64(index, flag);
1401 else
1402 SetFlag64(index, flag);
1403}
1404
1405bool Object::HasFlag64(uint16 index, uint64 flag) const
1406{
1407 ASSERT(index < m_valuesCount || PrintIndexError(index, false));
1408 return (GetUInt64Value(index) & flag) != 0;
1409}
1410
1411void Object::ApplyModFlag64(uint16 index, uint64 flag, bool apply)
1412{
1413 if (apply) SetFlag64(index, flag); else RemoveFlag64(index, flag);
1414}
1415
1416bool Object::PrintIndexError(uint32 index, bool set) const
1417{
1418 SF_LOG_ERROR("misc", "Attempt %s non-existed value field: %u (count: %u) for object typeid: %u type mask: %u", (set ? "set value to" : "get value from"), index, m_valuesCount, uint8(GetTypeId()), m_objectType);
1419
1420 // ASSERT must fail after function call
1421 return false;
1422}
1423
1425{
1426 return (G3D::fuzzyEq(a.m_positionX, m_positionX) &&
1427 G3D::fuzzyEq(a.m_positionY, m_positionY) &&
1428 G3D::fuzzyEq(a.m_positionZ, m_positionZ) &&
1429 G3D::fuzzyEq(a.m_orientation, m_orientation));
1430}
1431
1432bool Position::HasInLine(WorldObject const* target, float width) const
1433{
1434 if (!HasInArc(M_PI, target))
1435 return false;
1436 width += target->GetObjectSize();
1437 float angle = GetRelativeAngle(target);
1438 return fabs(sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width;
1439}
1440
1441std::string Position::ToString() const
1442{
1443 std::stringstream sstr;
1444 sstr << "X: " << m_positionX << " Y: " << m_positionY << " Z: " << m_positionZ << " O: " << m_orientation;
1445 return sstr.str();
1446}
1447
1449{
1450 float x, y, z, o;
1451 buf >> x >> y >> z >> o;
1452 streamer.m_pos->Relocate(x, y, z, o);
1453 return buf;
1454}
1456{
1457 float x, y, z;
1458 streamer.m_pos->GetPosition(x, y, z);
1459 buf << x << y << z;
1460 return buf;
1461}
1462
1464{
1465 float x, y, z;
1466 buf >> x >> y >> z;
1467 streamer.m_pos->Relocate(x, y, z);
1468 return buf;
1469}
1470
1472{
1473 float x, y, z, o;
1474 streamer.m_pos->GetPosition(x, y, z, o);
1475 buf << x << y << z << o;
1476 return buf;
1477}
1478
1480{
1481 SF_LOG_INFO("misc", "MOVEMENT INFO");
1482 SF_LOG_INFO("misc", "guid " UI64FMTD, guid);
1483 SF_LOG_INFO("misc", "flags %s (%u)", Movement::MovementFlags_ToString(flags).c_str(), flags);
1484 SF_LOG_INFO("misc", "flags2 %s (%u)", Movement::MovementFlagsExtra_ToString(flags2).c_str(), flags2);
1485 SF_LOG_INFO("misc", "time %u current time %u", time, getMSTime());
1486 SF_LOG_INFO("misc", "position: `%s`", pos.ToString().c_str());
1487 if (transport.guid)
1488 {
1489 SF_LOG_INFO("misc", "TRANSPORT:");
1490 SF_LOG_INFO("misc", "guid: " UI64FMTD, transport.guid);
1491 SF_LOG_INFO("misc", "position: `%s`", transport.pos.ToString().c_str());
1492 SF_LOG_INFO("misc", "seat: %i", transport.seat);
1493 SF_LOG_INFO("misc", "time: %u", transport.time);
1495 SF_LOG_INFO("misc", "time2: %u", transport.time2);
1496 if (transport.time3)
1497 SF_LOG_INFO("misc", "time3: %u", transport.time3);
1498 }
1499
1501 SF_LOG_INFO("misc", "pitch: %f", pitch);
1502
1503 if (flags & MOVEMENTFLAG_FALLING || jump.fallTime)
1504 {
1505 SF_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
1507 SF_LOG_INFO("misc", "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.sinAngle, jump.cosAngle, jump.xyspeed);
1508 }
1509
1511 SF_LOG_INFO("misc", "splineElevation: %f", splineElevation);
1512}
1513
1522
1524{
1525 if (!IsInWorld())
1526 return;
1527
1528 GetMap()->AddObjectToSwitchList(this, on);
1529}
1530
1532{
1533 if (m_isWorldObject)
1534 return true;
1535
1536 if (ToCreature() && ToCreature()->m_isTempWorldObject)
1537 return true;
1538
1539 return false;
1540}
1541
1543{
1544 if (m_isActive == on)
1545 return;
1546
1548 return;
1549
1550 m_isActive = on;
1551
1552 if (!IsInWorld())
1553 return;
1554
1555 Map* map = FindMap();
1556 if (!map)
1557 return;
1558
1559 if (on)
1560 {
1562 map->AddToActive(this->ToCreature());
1564 map->AddToActive((DynamicObject*)this);
1565 }
1566 else
1567 {
1569 map->RemoveFromActive(this->ToCreature());
1571 map->RemoveFromActive((DynamicObject*)this);
1572 }
1573}
1574
1575void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
1576{
1577 if (IsInWorld())
1579}
1580
1581void WorldObject::_Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask)
1582{
1583 Object::_Create(guidlow, 0, guidhigh);
1584 m_phaseMask = phaseMask;
1585}
1586
1588{
1589 if (!IsInWorld())
1590 return;
1591
1593
1595}
1596
1601
1606
1607void WorldObject::GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const
1608{
1610}
1611
1613{
1614 Map* map = GetMap();
1615 return map->IsInstance() ? ((InstanceMap*)map)->GetInstanceScript() : NULL;
1616}
1617
1619{
1620 float dz = fabs(GetPositionZ() - obj->GetPositionZ());
1621 float sizefactor = GetObjectSize() + obj->GetObjectSize();
1622 float dist = dz - sizefactor;
1623 return (dist > 0 ? dist : 0);
1624}
1625
1626bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const
1627{
1628 float sizefactor = GetObjectSize() + obj->GetObjectSize();
1629 float maxdist = dist2compare + sizefactor;
1630
1631 if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUIDLow() == m_transport->GetGUIDLow())
1632 {
1633 float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX;
1634 float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY;
1635 float disttsq = dtx * dtx + dty * dty;
1636 if (is3D)
1637 {
1638 float dtz = m_movementInfo.transport.pos.m_positionZ - obj->m_movementInfo.transport.pos.m_positionZ;
1639 disttsq += dtz * dtz;
1640 }
1641 return disttsq < (maxdist * maxdist);
1642 }
1643
1644 float dx = GetPositionX() - obj->GetPositionX();
1645 float dy = GetPositionY() - obj->GetPositionY();
1646 float distsq = dx * dx + dy * dy;
1647 if (is3D)
1648 {
1649 float dz = GetPositionZ() - obj->GetPositionZ();
1650 distsq += dz * dz;
1651 }
1652
1653 return distsq < maxdist * maxdist;
1654}
1655
1657{
1658 if (!IsInMap(obj))
1659 return false;
1660
1661 float ox, oy, oz;
1662 obj->GetPosition(ox, oy, oz);
1663 return IsWithinLOS(ox, oy, oz);
1664}
1665
1667{
1668 float d = GetExactDist(obj) - GetObjectSize() - obj->GetObjectSize();
1669 return d > 0.0f ? d : 0.0f;
1670}
1671
1672float WorldObject::GetDistance(const Position& pos) const
1673{
1674 float d = GetExactDist(&pos) - GetObjectSize();
1675 return d > 0.0f ? d : 0.0f;
1676}
1677
1678float WorldObject::GetDistance(float x, float y, float z) const
1679{
1680 float d = GetExactDist(x, y, z) - GetObjectSize();
1681 return d > 0.0f ? d : 0.0f;
1682}
1683
1685{
1686 float d = GetExactDist2d(obj) - GetObjectSize() - obj->GetObjectSize();
1687 return d > 0.0f ? d : 0.0f;
1688}
1689
1690float WorldObject::GetDistance2d(float x, float y) const
1691{
1692 float d = GetExactDist2d(x, y) - GetObjectSize();
1693 return d > 0.0f ? d : 0.0f;
1694}
1695
1697{
1698 if (this == obj)
1699 return true;
1700 return IsInMap(obj);
1701}
1702
1703bool WorldObject::IsInMap(const WorldObject* obj) const
1704{
1705 if (obj)
1706 return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap());
1707 return false;
1708}
1709
1710bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist) const
1711{
1712 return IsInDist(x, y, z, dist + GetObjectSize());
1713}
1714
1715bool WorldObject::IsWithinDist3d(const Position* pos, float dist) const
1716{
1717 return IsInDist(pos, dist + GetObjectSize());
1718}
1719
1720bool WorldObject::IsWithinDist2d(float x, float y, float dist) const
1721{
1722 return IsInDist2d(x, y, dist + GetObjectSize());
1723}
1724
1725bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const
1726{
1727 return IsInDist2d(pos, dist + GetObjectSize());
1728}
1729
1730bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
1731{
1732 return obj && _IsWithinDist(obj, dist2compare, is3D);
1733}
1734
1735bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const
1736{
1737 return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D);
1738}
1739
1740bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
1741{
1742 /*float x, y, z;
1743 GetPosition(x, y, z);
1744 VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
1745 return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);*/
1746 if (IsInWorld())
1747 return GetMap()->isInLineOfSight(GetPositionX(), GetPositionY(), GetPositionZ() + 2.f, ox, oy, oz + 2.f, GetPhaseMask());
1748
1749 return true;
1750}
1751
1752bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const
1753{
1754 float dx1 = GetPositionX() - obj1->GetPositionX();
1755 float dy1 = GetPositionY() - obj1->GetPositionY();
1756 float distsq1 = dx1 * dx1 + dy1 * dy1;
1757 if (is3D)
1758 {
1759 float dz1 = GetPositionZ() - obj1->GetPositionZ();
1760 distsq1 += dz1 * dz1;
1761 }
1762
1763 float dx2 = GetPositionX() - obj2->GetPositionX();
1764 float dy2 = GetPositionY() - obj2->GetPositionY();
1765 float distsq2 = dx2 * dx2 + dy2 * dy2;
1766 if (is3D)
1767 {
1768 float dz2 = GetPositionZ() - obj2->GetPositionZ();
1769 distsq2 += dz2 * dz2;
1770 }
1771
1772 return distsq1 < distsq2;
1773}
1774
1775bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D /* = true */) const
1776{
1777 float dx = GetPositionX() - obj->GetPositionX();
1778 float dy = GetPositionY() - obj->GetPositionY();
1779 float distsq = dx * dx + dy * dy;
1780 if (is3D)
1781 {
1782 float dz = GetPositionZ() - obj->GetPositionZ();
1783 distsq += dz * dz;
1784 }
1785
1786 float sizefactor = GetObjectSize() + obj->GetObjectSize();
1787
1788 // check only for real range
1789 if (minRange > 0.0f)
1790 {
1791 float mindist = minRange + sizefactor;
1792 if (distsq < mindist * mindist)
1793 return false;
1794 }
1795
1796 float maxdist = maxRange + sizefactor;
1797 return distsq < maxdist * maxdist;
1798}
1799
1800bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) const
1801{
1802 float dx = GetPositionX() - x;
1803 float dy = GetPositionY() - y;
1804 float distsq = dx * dx + dy * dy;
1805
1806 float sizefactor = GetObjectSize();
1807
1808 // check only for real range
1809 if (minRange > 0.0f)
1810 {
1811 float mindist = minRange + sizefactor;
1812 if (distsq < mindist * mindist)
1813 return false;
1814 }
1815
1816 float maxdist = maxRange + sizefactor;
1817 return distsq < maxdist * maxdist;
1818}
1819
1820bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float maxRange) const
1821{
1822 float dx = GetPositionX() - x;
1823 float dy = GetPositionY() - y;
1824 float dz = GetPositionZ() - z;
1825 float distsq = dx * dx + dy * dy + dz * dz;
1826
1827 float sizefactor = GetObjectSize();
1828
1829 // check only for real range
1830 if (minRange > 0.0f)
1831 {
1832 float mindist = minRange + sizefactor;
1833 if (distsq < mindist * mindist)
1834 return false;
1835 }
1836
1837 float maxdist = maxRange + sizefactor;
1838 return distsq < maxdist * maxdist;
1839}
1840
1842{
1843 m_positionX = GetPositionX() + (offset.GetPositionX() * std::cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + M_PI));
1844 m_positionY = GetPositionY() + (offset.GetPositionY() * std::cos(GetOrientation()) + offset.GetPositionX() * std::sin(GetOrientation()));
1845 m_positionZ = GetPositionZ() + offset.GetPositionZ();
1847}
1848
1849void Position::GetPositionOffsetTo(const Position& endPos, Position& retOffset) const
1850{
1851 float dx = endPos.GetPositionX() - GetPositionX();
1852 float dy = endPos.GetPositionY() - GetPositionY();
1853
1854 retOffset.m_positionX = dx * std::cos(GetOrientation()) + dy * std::sin(GetOrientation());
1855 retOffset.m_positionY = dy * std::cos(GetOrientation()) - dx * std::sin(GetOrientation());
1856 retOffset.m_positionZ = endPos.GetPositionZ() - GetPositionZ();
1857 retOffset.SetOrientation(endPos.GetOrientation() - GetOrientation());
1858}
1859
1860float Position::GetAngle(const Position* obj) const
1861{
1862 if (!obj)
1863 return 0;
1864
1865 return GetAngle(obj->GetPositionX(), obj->GetPositionY());
1866}
1867
1868// Return angle in range 0..2*pi
1869float Position::GetAngle(const float x, const float y) const
1870{
1871 float dx = x - GetPositionX();
1872 float dy = y - GetPositionY();
1873
1874 float ang = atan2(dy, dx);
1875 ang = (ang >= 0) ? ang : 2 * M_PI + ang;
1876 return ang;
1877}
1878
1879void Position::GetSinCos(const float x, const float y, float& vsin, float& vcos) const
1880{
1881 float dx = GetPositionX() - x;
1882 float dy = GetPositionY() - y;
1883
1884 if (fabs(dx) < 0.001f && fabs(dy) < 0.001f)
1885 {
1886 float angle = (float)rand_norm() * static_cast<float>(2 * M_PI);
1887 vcos = std::cos(angle);
1888 vsin = std::sin(angle);
1889 }
1890 else
1891 {
1892 float dist = sqrt((dx * dx) + (dy * dy));
1893 vcos = dx / dist;
1894 vsin = dy / dist;
1895 }
1896}
1897
1898bool Position::HasInArc(float arc, const Position* obj, float border) const
1899{
1900 // always have self in arc
1901 if (obj == this)
1902 return true;
1903
1904 // move arc to range 0.. 2*pi
1905 arc = NormalizeOrientation(arc);
1906
1907 float angle = GetAngle(obj);
1908 angle -= m_orientation;
1909
1910 // move angle to range -pi ... +pi
1911 angle = NormalizeOrientation(angle);
1912 if (angle > M_PI)
1913 angle -= 2.0f * M_PI;
1914
1915 float lborder = -1 * (arc / border); // in range -pi..0
1916 float rborder = (arc / border); // in range 0..pi
1917 return ((angle >= lborder) && (angle <= rborder));
1918}
1919
1920bool WorldObject::IsInBetween(const WorldObject* obj1, const WorldObject* obj2, float size) const
1921{
1922 if (!obj1 || !obj2)
1923 return false;
1924
1925 float dist = GetExactDist2d(obj1->GetPositionX(), obj1->GetPositionY());
1926
1927 // not using sqrt() for performance
1928 if ((dist * dist) >= obj1->GetExactDist2dSq(obj2->GetPositionX(), obj2->GetPositionY()))
1929 return false;
1930
1931 if (!size)
1932 size = GetObjectSize() / 2;
1933
1934 float angle = obj1->GetAngle(obj2);
1935
1936 // not using sqrt() for performance
1937 return (size * size) >= GetExactDist2dSq(obj1->GetPositionX() + std::cos(angle) * dist, obj1->GetPositionY() + std::sin(angle) * dist);
1938}
1939
1940bool WorldObject::isInFront(WorldObject const* target, float arc) const
1941{
1942 return HasInArc(arc, target);
1943}
1944
1945bool WorldObject::isInBack(WorldObject const* target, float arc) const
1946{
1947 return !HasInArc(2 * M_PI - arc, target);
1948}
1949
1950void WorldObject::GetRandomPoint(const Position& pos, float distance, float& rand_x, float& rand_y, float& rand_z) const
1951{
1952 if (!distance)
1953 {
1954 pos.GetPosition(rand_x, rand_y, rand_z);
1955 return;
1956 }
1957
1958 // angle to face `obj` to `this`
1959 float angle = (float)rand_norm() * static_cast<float>(2 * M_PI);
1960 float new_dist = (float)rand_norm() * static_cast<float>(distance);
1961
1962 rand_x = pos.m_positionX + new_dist * std::cos(angle);
1963 rand_y = pos.m_positionY + new_dist * std::sin(angle);
1964 rand_z = pos.m_positionZ;
1965
1968 UpdateGroundPositionZ(rand_x, rand_y, rand_z); // update to LOS height if available
1969}
1970
1971void WorldObject::GetRandomPoint(const Position& srcPos, float distance, Position& pos) const
1972{
1973 float x, y, z;
1974 GetRandomPoint(srcPos, distance, x, y, z);
1975 pos.Relocate(x, y, z, GetOrientation());
1976}
1977
1978void WorldObject::UpdateGroundPositionZ(float x, float y, float& z) const
1979{
1980 float new_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
1981 if (new_z > INVALID_HEIGHT)
1982 z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
1983}
1984
1985void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z) const
1986{
1987 switch (GetTypeId())
1988 {
1990 {
1991 // non fly unit don't must be in air
1992 // non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
1993 if (!ToCreature()->CanFly())
1994 {
1995 bool canSwim = ToCreature()->CanSwim();
1996 float ground_z = z;
1997 float max_z = canSwim
1998 ? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
1999 : ((ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true)));
2000 if (max_z > INVALID_HEIGHT)
2001 {
2002 if (z > max_z)
2003 z = max_z;
2004 else if (z < ground_z)
2005 z = ground_z;
2006 }
2007 }
2008 else
2009 {
2010 float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
2011 if (z < ground_z)
2012 z = ground_z;
2013 }
2014 break;
2015 }
2017 {
2018 // for server controlled moves playr work same as creature (but it can always swim)
2019 if (!ToPlayer()->CanFly())
2020 {
2021 float ground_z = z;
2022 float max_z = GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
2023 if (max_z > INVALID_HEIGHT)
2024 {
2025 if (z > max_z)
2026 z = max_z;
2027 else if (z < ground_z)
2028 z = ground_z;
2029 }
2030 }
2031 else
2032 {
2033 float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
2034 if (z < ground_z)
2035 z = ground_z;
2036 }
2037 break;
2038 }
2039 default:
2040 {
2041 float ground_z = GetBaseMap()->GetHeight(GetPhaseMask(), x, y, z, true);
2042 if (ground_z > INVALID_HEIGHT)
2043 z = ground_z;
2044 break;
2045 }
2046 }
2047}
2048
2053
2055{
2056 if (isActiveObject())
2057 {
2058 if (GetTypeId() == TypeID::TYPEID_PLAYER && ToPlayer()->IsInCinematic())
2060
2061 return GetMap()->GetVisibilityRange();
2062 }
2063
2064 if (Creature const* thisCreature = ToCreature())
2065 return thisCreature->m_SightDistance;
2066
2067 return 0.0f;
2068}
2069
2071{
2072 if (isActiveObject() && !ToPlayer())
2074 else
2075 return GetMap()->GetVisibilityRange();
2076}
2077
2078float WorldObject::GetSightRange(const WorldObject* target) const
2079{
2080 if (ToUnit())
2081 {
2082 if (ToPlayer())
2083 {
2084 if (target && target->isActiveObject() && !target->ToPlayer())
2086 else if (ToPlayer()->IsInCinematic())
2088 else
2089 return GetMap()->GetVisibilityRange();
2090 }
2091 else if (ToCreature())
2092 return ToCreature()->m_SightDistance;
2093 else
2094 return SIGHT_RANGE_UNIT;
2095 }
2096
2097 if (ToDynObject() && isActiveObject())
2098 {
2099 return GetMap()->GetVisibilityRange();
2100 }
2101
2102 return 0.0f;
2103}
2104
2105bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, bool distanceCheck) const
2106{
2107 if (this == obj)
2108 return true;
2109
2110 if (obj->IsNeverVisible() || CanNeverSee(obj))
2111 return false;
2112
2113 if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj))
2114 return true;
2115
2116 bool corpseVisibility = false;
2117 if (distanceCheck)
2118 {
2119 bool corpseCheck = false;
2120 if (Player const* thisPlayer = ToPlayer())
2121 {
2122 if (thisPlayer->isDead() && thisPlayer->GetHealth() > 0 && // Cheap way to check for ghost state
2124 {
2125 if (Corpse* corpse = thisPlayer->GetCorpse())
2126 {
2127 corpseCheck = true;
2128 if (corpse->IsWithinDist(thisPlayer, GetSightRange(obj), false))
2129 if (corpse->IsWithinDist(obj, GetSightRange(obj), false))
2130 corpseVisibility = true;
2131 }
2132 }
2133 }
2134
2135 bool isWithinSight = false;
2136 if (Player const* player = this->ToPlayer())
2137 {
2138 float cinematicX, cinematicY, cinematicZ;
2139 if (player->GetCinematicPosition(cinematicX, cinematicY, cinematicZ))
2140 isWithinSight = obj->IsWithinDist2d(cinematicX, cinematicY, GetSightRange(obj));
2141 else if (WorldObject const* viewpoint = player->GetViewpoint())
2142 isWithinSight = viewpoint->IsWithinDist(obj, GetSightRange(obj), false);
2143 else
2144 isWithinSight = IsWithinDist(obj, GetSightRange(obj), false);
2145 }
2146 else
2147 isWithinSight = IsWithinDist(obj, GetSightRange(obj), false);
2148
2149 if (!corpseCheck && !isWithinSight)
2150 return false;
2151 }
2152
2153 // GM visibility off or hidden NPC
2155 {
2156 // Stop checking other things for GMs
2158 return true;
2159 }
2160 else
2162
2163 // Ghost players, Spirit Healers, and some other NPCs
2165 {
2166 // Alive players can see dead players in some cases, but other objects can't do that
2167 if (Player const* thisPlayer = ToPlayer())
2168 {
2169 if (Player const* objPlayer = obj->ToPlayer())
2170 {
2171 if (thisPlayer->GetTeam() != objPlayer->GetTeam() || !thisPlayer->IsGroupVisibleFor(objPlayer))
2172 return false;
2173 }
2174 else
2175 return false;
2176 }
2177 else
2178 return false;
2179 }
2180
2181 if (obj->IsInvisibleDueToDespawn())
2182 return false;
2183
2184 if (!CanDetect(obj, ignoreStealth))
2185 return false;
2186
2187 return true;
2188}
2189
2191{
2192 return GetMap() != obj->GetMap() || !InSamePhase(obj);
2193}
2194
2195bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const
2196{
2197 const WorldObject* seer = this;
2198
2199 // Pets don't have detection, they use the detection of their masters
2200 if (Unit const* thisUnit = ToUnit())
2201 if (Unit* controller = thisUnit->GetCharmerOrOwner())
2202 seer = controller;
2203
2204 if (obj->IsAlwaysDetectableFor(seer))
2205 return true;
2206
2207 if (!ignoreStealth && !seer->CanDetectInvisibilityOf(obj))
2208 return false;
2209
2210 if (!ignoreStealth && !seer->CanDetectStealthOf(obj))
2211 return false;
2212
2213 return true;
2214}
2215
2217{
2218 uint32 mask = obj->m_invisibility.GetFlags() & m_invisibilityDetect.GetFlags();
2219
2220 // Check for not detected types
2221 if (mask != obj->m_invisibility.GetFlags())
2222 return false;
2223
2224 for (uint32 i = 0; i < TOTAL_INVISIBILITY_TYPES; ++i)
2225 {
2226 if (!(mask & (1 << i)))
2227 continue;
2228
2229 int32 objInvisibilityValue = obj->m_invisibility.GetValue(InvisibilityType(i));
2230 int32 ownInvisibilityDetectValue = m_invisibilityDetect.GetValue(InvisibilityType(i));
2231
2232 // Too low value to detect
2233 if (ownInvisibilityDetectValue < objInvisibilityValue)
2234 return false;
2235 }
2236
2237 return true;
2238}
2239
2241{
2242 // Combat reach is the minimal distance (both in front and behind),
2243 // and it is also used in the range calculation.
2244 // One stealth point increases the visibility range by 0.3 yard.
2245
2246 if (!obj->m_stealth.GetFlags())
2247 return true;
2248
2249 float distance = GetExactDist(obj);
2250 float combatReach = 0.0f;
2251
2252 Unit const* unit = ToUnit();
2253 if (unit)
2254 combatReach = unit->GetCombatReach();
2255
2256 if (distance < combatReach)
2257 return true;
2258
2259 if (!HasInArc(M_PI, obj))
2260 return false;
2261
2262 GameObject const* go = ToGameObject();
2263 for (uint32 i = 0; i < TOTAL_STEALTH_TYPES; ++i)
2264 {
2265 if (!(obj->m_stealth.GetFlags() & (1 << i)))
2266 continue;
2267
2269 return true;
2270
2271 // Starting points
2272 int32 detectionValue = 30;
2273
2274 // Level difference: 5 point / level, starting from level 1.
2275 // There may be spells for this and the starting points too, but
2276 // not in the DBCs of the client.
2277 detectionValue += int32(getLevelForTarget(obj) - 1) * 5;
2278
2279 // Apply modifiers
2280 detectionValue += m_stealthDetect.GetValue(StealthType(i));
2281 if (go)
2282 if (Unit* owner = go->GetOwner())
2283 detectionValue -= int32(owner->getLevelForTarget(this) - 1) * 5;
2284
2285 detectionValue -= obj->m_stealth.GetValue(StealthType(i));
2286
2287 // Calculate max distance
2288 float visibilityRange = float(detectionValue) * 0.3f + combatReach;
2289
2290 if (visibilityRange > MAX_PLAYER_STEALTH_DETECT_RANGE)
2291 visibilityRange = MAX_PLAYER_STEALTH_DETECT_RANGE;
2292
2293 if (distance > visibilityRange)
2294 return false;
2295 }
2296
2297 return true;
2298}
2299
2301{
2302 ObjectGuid guid = GetGUID();
2303
2304 WorldPacket data(SMSG_PLAY_SOUND, 4 + 9);
2305 data.WriteBit(guid[2]);
2306 data.WriteBit(guid[3]);
2307 data.WriteBit(guid[7]);
2308 data.WriteBit(guid[6]);
2309 data.WriteBit(guid[0]);
2310 data.WriteBit(guid[5]);
2311 data.WriteBit(guid[4]);
2312 data.WriteBit(guid[1]);
2313 data << uint32(Sound);
2314 data.WriteByteSeq(guid[3]);
2315 data.WriteByteSeq(guid[2]);
2316 data.WriteByteSeq(guid[4]);
2317 data.WriteByteSeq(guid[7]);
2318 data.WriteByteSeq(guid[5]);
2319 data.WriteByteSeq(guid[0]);
2320 data.WriteByteSeq(guid[6]);
2321 data.WriteByteSeq(guid[1]);
2322 if (OnlySelf && GetTypeId() == TypeID::TYPEID_PLAYER)
2323 this->ToPlayer()->GetSession()->SendPacket(&data);
2324 else
2325 SendMessageToSet(&data, true); // ToSelf ignored in this case
2326}
2327
2329{
2330 _changesMask.SetBit(i);
2331 if (m_inWorld && !m_objectUpdated)
2332 {
2333 sObjectAccessor->AddUpdateObject(this);
2334 m_objectUpdated = true;
2335 }
2336}
2337
2338namespace Skyfire
2339{
2341 {
2342 public:
2343 MonsterChatBuilder(WorldObject const* obj, ChatMsg msgtype, int32 textId, Language language, WorldObject const* target)
2344 : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language), i_target(target) { }
2345
2347 {
2348 char const* text = sObjectMgr->GetSkyFireString(i_textId, loc_idx);
2349
2351 ChatHandler::BuildChatPacket(data, i_msgtype, i_language, i_object, i_target, text, 0, "", loc_idx);
2352 }
2353
2354 private:
2360 };
2361
2363 {
2364 public:
2365 MonsterCustomChatBuilder(WorldObject const* obj, ChatMsg msgtype, const char* text, Language language, WorldObject const* target)
2366 : i_object(obj), i_msgtype(msgtype), i_text(text), i_language(language), i_target(target) { }
2367
2369 {
2372 }
2373
2374 private:
2377 const char* i_text;
2380 };
2381} // namespace Skyfire
2382
2396
2410
2424
2438
2439
2440void WorldObject::MonsterTextEmote(const char* text, WorldObject const* target, bool IsBossEmote)
2441{
2442 WorldPacket data;
2445}
2446
2460
2461void WorldObject::MonsterWhisper(const char* text, Player const* target, bool IsBossWhisper)
2462{
2463 if (!target)
2464 return;
2465
2466 LocaleConstant loc_idx = target->GetSession()->GetSessionDbLocaleIndex();
2467 WorldPacket data;
2469 target->GetSession()->SendPacket(&data);
2470}
2471
2472void WorldObject::MonsterWhisper(int32 textId, Player const* target, bool IsBossWhisper)
2473{
2474 if (!target)
2475 return;
2476
2477 LocaleConstant loc_idx = target->GetSession()->GetSessionDbLocaleIndex();
2478 char const* text = sObjectMgr->GetSkyFireString(textId, loc_idx);
2479
2480 WorldPacket data;
2482 target->GetSession()->SendPacket(&data);
2483}
2484
2486{
2487 if (IsInWorld())
2489}
2490
2491void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/)
2492{
2493 Skyfire::MessageDistDeliverer notifier(this, data, dist);
2494 VisitNearbyWorldObject(dist, notifier);
2495}
2496
2497void WorldObject::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr)
2498{
2499 Skyfire::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr);
2501}
2502
2504{
2505 ObjectGuid Guid = guid;
2507
2508 data.WriteGuidMask(Guid, 0, 2, 4, 1, 7, 3, 6, 5);
2509 data.WriteGuidBytes(Guid, 0, 2, 4, 5, 7, 3, 1, 6);
2510
2511 SendMessageToSet(&data, true);
2512}
2513
2515{
2516 ASSERT(map);
2518 if (m_currMap == map) // command add npc: first create, than loadfromdb
2519 return;
2520 if (m_currMap)
2521 {
2522 SF_LOG_FATAL("misc", "WorldObject::SetMap: obj %u new map %u %u, old map %u %u", (uint32)GetTypeId(), map->GetId(), map->GetInstanceId(), m_currMap->GetId(), m_currMap->GetInstanceId());
2523 ASSERT(false);
2524 }
2525 m_currMap = map;
2526 m_mapId = map->GetId();
2527 m_InstanceId = map->GetInstanceId();
2528 if (IsWorldObject())
2529 m_currMap->AddWorldObject(this);
2530}
2531
2533{
2535 ASSERT(!IsInWorld());
2536 if (IsWorldObject())
2537 m_currMap->RemoveWorldObject(this);
2538 m_currMap = NULL;
2539 //maybe not for corpse
2540 //m_mapId = 0;
2541 //m_InstanceId = 0;
2542}
2543
2545{
2547 return m_currMap->GetParent();
2548}
2549
2551{
2553
2554 Map* map = FindMap();
2555 if (!map)
2556 {
2557 SF_LOG_ERROR("misc", "Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).", uint8(GetTypeId()), GetEntry(), GetGUIDLow(), GetMapId());
2558 return;
2559 }
2560
2561 map->AddObjectToRemoveList(this);
2562}
2563
2564TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/)
2565{
2566 uint32 mask = UNIT_MASK_SUMMON;
2567 if (properties)
2568 {
2569 switch (properties->Category)
2570 {
2572 mask = UNIT_MASK_GUARDIAN;
2573 break;
2575 mask = UNIT_MASK_PUPPET;
2576 break;
2578 mask = UNIT_MASK_MINION;
2579 break;
2583 {
2584 switch (properties->Type)
2585 {
2586 case SUMMON_TYPE_MINION:
2589 mask = UNIT_MASK_GUARDIAN;
2590 break;
2591 case SUMMON_TYPE_STATUE:
2592 case SUMMON_TYPE_TOTEM:
2594 mask = UNIT_MASK_TOTEM;
2595 break;
2598 mask = UNIT_MASK_SUMMON;
2599 break;
2601 mask = UNIT_MASK_MINION;
2602 break;
2603 default:
2604 if (properties->Flags & 512) // Mirror Image, Summon Gargoyle
2605 mask = UNIT_MASK_GUARDIAN;
2606 break;
2607 }
2608 break;
2609 }
2610 default:
2611 return NULL;
2612 }
2613 }
2614
2615 uint32 phase = PHASEMASK_NORMAL;
2616 std::set<uint32> phases;
2617 uint32 team = 0;
2618 if (summoner)
2619 {
2620 phase = summoner->GetPhaseMask();
2621 if (summoner->GetTypeId() == TypeID::TYPEID_PLAYER)
2622 team = summoner->ToPlayer()->GetTeam();
2623
2624 phases = summoner->GetPhases();
2625 }
2626
2627 TempSummon* summon = NULL;
2628 switch (mask)
2629 {
2630 case UNIT_MASK_SUMMON:
2631 summon = new TempSummon(properties, summoner, false);
2632 break;
2633 case UNIT_MASK_GUARDIAN:
2634 summon = new Guardian(properties, summoner, false);
2635 break;
2636 case UNIT_MASK_PUPPET:
2637 summon = new Puppet(properties, summoner);
2638 break;
2639 case UNIT_MASK_TOTEM:
2640 summon = new Totem(properties, summoner);
2641 break;
2642 case UNIT_MASK_MINION:
2643 summon = new Minion(properties, summoner, false);
2644 break;
2645 }
2646
2647 if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, entry, vehId, team, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
2648 {
2649 delete summon;
2650 return NULL;
2651 }
2652
2653 for (auto phaseId : phases)
2654 summon->SetPhased(phaseId, false, true);
2656
2657 summon->SetHomePosition(pos);
2658
2659 summon->InitStats(duration);
2660 AddToMap(summon->ToCreature());
2661 summon->InitSummon();
2662
2663 //ObjectAccessor::UpdateObjectVisibility(summon);
2664
2665 return summon;
2666}
2667
2674
2675void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= NULL*/)
2676{
2677 std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetId(), SummonerType::SUMMONER_TYPE_MAP, group);
2678 if (!data)
2679 return;
2680
2681 for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
2682 if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, NULL, itr->time))
2683 if (list)
2684 list->push_back(summon);
2685}
2686
2688{
2689 if (Map* map = FindMap())
2690 {
2691 if (map->IsInstance())
2692 m_zoneScript = (ZoneScript*)((InstanceMap*)map)->GetInstanceScript();
2693 else if (!map->IsBattlegroundOrArena())
2694 {
2695 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId()))
2696 m_zoneScript = bf;
2697 else
2698 m_zoneScript = sOutdoorPvPMgr->GetZoneScript(GetZoneId());
2699 }
2700 }
2701}
2702
2703TempSummon* WorldObject::SummonCreature(uint32 entry, const Position& pos, TempSummonType spwtype, uint32 duration, uint32 /*vehId*/) const
2704{
2705 if (Map* map = FindMap())
2706 {
2707 if (TempSummon* summon = map->SummonCreature(entry, pos, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL))
2708 {
2709 summon->SetTempSummonType(spwtype);
2710 return summon;
2711 }
2712 }
2713
2714 return NULL;
2715}
2716
2717TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang /*= 0*/, TempSummonType spwtype /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 despwtime /*= 0*/) const
2718{
2719 if (!x && !y && !z)
2720 {
2721 GetClosePoint(x, y, z, GetObjectSize());
2722 ang = GetOrientation();
2723 }
2724 Position pos;
2725 pos.Relocate(x, y, z, ang);
2726 return SummonCreature(id, pos, spwtype, despwtime, 0);
2727}
2728
2729GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
2730{
2731 if (!IsInWorld())
2732 return NULL;
2733
2734 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry);
2735 if (!goinfo)
2736 {
2737 SF_LOG_ERROR("sql.sql", "Gameobject template %u not found in database!", entry);
2738 return NULL;
2739 }
2740
2741 Map* map = GetMap();
2742 GameObject* go = new GameObject();
2743 if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GOState::GO_STATE_READY))
2744 {
2745 delete go;
2746 return NULL;
2747 }
2748
2749 for (auto phase : GetPhases())
2750 go->SetPhased(phase, false, true);
2751
2752 go->SetRespawnTime(respawnTime);
2753 if (GetTypeId() == TypeID::TYPEID_PLAYER || GetTypeId() == TypeID::TYPEID_UNIT) //not sure how to handle this
2754 ToUnit()->AddGameObject(go);
2755 else
2756 go->SetSpawnedByDefault(false);
2757
2758 map->AddToMap(go);
2759 return go;
2760}
2761
2762Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint32 duration, CreatureAI* (*GetAI)(Creature*))
2763{
2765 Creature* summon = SummonCreature(WORLD_TRIGGER, x, y, z, ang, summonType, duration);
2766 if (!summon)
2767 return NULL;
2768
2769 //summon->SetName(GetName());
2771 {
2772 summon->setFaction(((Unit*)this)->getFaction());
2773 summon->SetLevel(((Unit*)this)->getLevel());
2774 }
2775
2776 if (GetAI)
2777 summon->AIM_Initialize(GetAI(summon));
2778 return summon;
2779}
2780
2787void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= NULL*/)
2788{
2789 ASSERT((GetTypeId() == TypeID::TYPEID_GAMEOBJECT || GetTypeId() == TypeID::TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!");
2790
2791 std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetEntry(), GetTypeId() == TypeID::TYPEID_GAMEOBJECT ? SummonerType::SUMMONER_TYPE_GAMEOBJECT : SummonerType::SUMMONER_TYPE_CREATURE, group);
2792 if (!data)
2793 return;
2794
2795 for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
2796 if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, itr->time))
2797 if (list)
2798 list->push_back(summon);
2799}
2800
2801Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive) const
2802{
2803 Creature* creature = NULL;
2804 Skyfire::NearestCreatureEntryWithLiveStateInObjectRangeCheck checker(*this, entry, alive, range);
2806 VisitNearbyObject(range, searcher);
2807 return creature;
2808}
2809
2811{
2812 GameObject* go = NULL;
2813 Skyfire::NearestGameObjectEntryInObjectRangeCheck checker(*this, entry, range);
2815 VisitNearbyGridObject(range, searcher);
2816 return go;
2817}
2818
2820{
2821 GameObject* go = NULL;
2822 Skyfire::NearestGameObjectTypeInObjectRangeCheck checker(*this, type, range);
2824 VisitNearbyGridObject(range, searcher);
2825 return go;
2826}
2827
2828void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>& gameobjectList, uint32 entry, float maxSearchRange) const
2829{
2831 Cell cell(pair);
2832 cell.SetNoCreate();
2833
2834 Skyfire::AllGameObjectsWithEntryInRange check(this, entry, maxSearchRange);
2837
2838 cell.Visit(pair, visitor, *(this->GetMap()), *this, maxSearchRange);
2839}
2840
2841void WorldObject::GetCreatureListWithEntryInGrid(std::list<Creature*>& creatureList, uint32 entry, float maxSearchRange) const
2842{
2844 Cell cell(pair);
2845 cell.SetNoCreate();
2846
2847 Skyfire::AllCreaturesOfEntryInRange check(this, entry, maxSearchRange);
2850
2851 cell.Visit(pair, visitor, *(this->GetMap()), *this, maxSearchRange);
2852}
2853
2854void WorldObject::GetPlayerListInGrid(std::list<Player*>& playerList, float maxSearchRange) const
2855{
2856 Skyfire::AnyPlayerInObjectRangeCheck checker(this, maxSearchRange);
2858 this->VisitNearbyWorldObject(maxSearchRange, searcher);
2859}
2860
2861/*
2862namespace Skyfire
2863{
2864 class NearUsedPosDo
2865 {
2866 public:
2867 NearUsedPosDo(WorldObject const& obj, WorldObject const* searcher, float angle, ObjectPosSelector& selector)
2868 : i_object(obj), i_searcher(searcher), i_angle(angle), i_selector(selector) { }
2869
2870 void operator()(Corpse*) const { }
2871 void operator()(DynamicObject*) const { }
2872
2873 void operator()(Creature* c) const
2874 {
2875 // skip self or target
2876 if (c == i_searcher || c == &i_object)
2877 return;
2878
2879 float x, y, z;
2880
2881 if (!c->IsAlive() || c->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DISTRACTED) ||
2882 !c->GetMotionMaster()->GetDestination(x, y, z))
2883 {
2884 x = c->GetPositionX();
2885 y = c->GetPositionY();
2886 }
2887
2888 add(c, x, y);
2889 }
2890
2891 template<class T>
2892 void operator()(T* u) const
2893 {
2894 // skip self or target
2895 if (u == i_searcher || u == &i_object)
2896 return;
2897
2898 float x, y;
2899
2900 x = u->GetPositionX();
2901 y = u->GetPositionY();
2902
2903 add(u, x, y);
2904 }
2905
2906 // we must add used pos that can fill places around center
2907 void add(WorldObject* u, float x, float y) const
2908 {
2909 // u is too nearest/far away to i_object
2910 if (!i_object.IsInRange2d(x, y, i_selector.m_dist - i_selector.m_size, i_selector.m_dist + i_selector.m_size))
2911 return;
2912
2913 float angle = i_object.GetAngle(u)-i_angle;
2914
2915 // move angle to range -pi ... +pi
2916 while (angle > M_PI)
2917 angle -= 2.0f * M_PI;
2918 while (angle < -M_PI)
2919 angle += 2.0f * M_PI;
2920
2921 // dist include size of u
2922 float dist2d = i_object.GetDistance2d(x, y);
2923 i_selector.AddUsedPos(u->GetObjectSize(), angle, dist2d + i_object.GetObjectSize());
2924 }
2925 private:
2926 WorldObject const& i_object;
2927 WorldObject const* i_searcher;
2928 float i_angle;
2929 ObjectPosSelector& i_selector;
2930 };
2931} // namespace Skyfire
2932*/
2933
2934//===================================================================================================
2935
2936void WorldObject::GetNearPoint2D(float& x, float& y, float distance2d, float absAngle) const
2937{
2938 x = GetPositionX() + (GetObjectSize() + distance2d) * std::cos(absAngle);
2939 y = GetPositionY() + (GetObjectSize() + distance2d) * std::sin(absAngle);
2940
2943}
2944
2945void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float& x, float& y, float& z, float searcher_size, float distance2d, float absAngle) const
2946{
2947 GetNearPoint2D(x, y, distance2d + searcher_size, absAngle);
2948 z = GetPositionZ();
2949 UpdateAllowedPositionZ(x, y, z);
2950
2951 /*
2952 // if detection disabled, return first point
2953 if (!sWorld->getIntConfig(CONFIG_DETECT_POS_COLLISION))
2954 {
2955 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
2956 return;
2957 }
2958
2959 // or remember first point
2960 float first_x = x;
2961 float first_y = y;
2962 bool first_los_conflict = false; // first point LOS problems
2963
2964 // prepare selector for work
2965 ObjectPosSelector selector(GetPositionX(), GetPositionY(), GetObjectSize(), distance2d+searcher_size);
2966
2967 // adding used positions around object
2968 {
2969 CellCoord p(Skyfire::ComputeCellCoord(GetPositionX(), GetPositionY()));
2970 Cell cell(p);
2971 cell.SetNoCreate();
2972
2973 Skyfire::NearUsedPosDo u_do(*this, searcher, absAngle, selector);
2974 Skyfire::WorldObjectWorker<Skyfire::NearUsedPosDo> worker(this, u_do);
2975
2976 TypeContainerVisitor<Skyfire::WorldObjectWorker<Skyfire::NearUsedPosDo>, GridTypeMapContainer > grid_obj_worker(worker);
2977 TypeContainerVisitor<Skyfire::WorldObjectWorker<Skyfire::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
2978
2979 CellLock<GridReadGuard> cell_lock(cell, p);
2980 cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
2981 cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
2982 }
2983
2984 // maybe can just place in primary position
2985 if (selector.CheckOriginal())
2986 {
2987 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
2988
2989 if (IsWithinLOS(x, y, z))
2990 return;
2991
2992 first_los_conflict = true; // first point have LOS problems
2993 }
2994
2995 float angle; // candidate of angle for free pos
2996
2997 // special case when one from list empty and then empty side preferred
2998 if (selector.FirstAngle(angle))
2999 {
3000 GetNearPoint2D(x, y, distance2d, absAngle+angle);
3001 z = GetPositionZ();
3002 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
3003
3004 if (IsWithinLOS(x, y, z))
3005 return;
3006 }
3007
3008 // set first used pos in lists
3009 selector.InitializeAngle();
3010
3011 // select in positions after current nodes (selection one by one)
3012 while (selector.NextAngle(angle)) // angle for free pos
3013 {
3014 GetNearPoint2D(x, y, distance2d, absAngle+angle);
3015 z = GetPositionZ();
3016 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
3017
3018 if (IsWithinLOS(x, y, z))
3019 return;
3020 }
3021
3022 // BAD NEWS: not free pos (or used or have LOS problems)
3023 // Attempt find _used_ pos without LOS problem
3024
3025 if (!first_los_conflict)
3026 {
3027 x = first_x;
3028 y = first_y;
3029
3030 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
3031 return;
3032 }
3033
3034 // special case when one from list empty and then empty side preferred
3035 if (selector.IsNonBalanced())
3036 {
3037 if (!selector.FirstAngle(angle)) // _used_ pos
3038 {
3039 GetNearPoint2D(x, y, distance2d, absAngle+angle);
3040 z = GetPositionZ();
3041 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
3042
3043 if (IsWithinLOS(x, y, z))
3044 return;
3045 }
3046 }
3047
3048 // set first used pos in lists
3049 selector.InitializeAngle();
3050
3051 // select in positions after current nodes (selection one by one)
3052 while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem
3053 {
3054 GetNearPoint2D(x, y, distance2d, absAngle+angle);
3055 z = GetPositionZ();
3056 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
3057
3058 if (IsWithinLOS(x, y, z))
3059 return;
3060 }
3061
3062 // BAD BAD NEWS: all found pos (free and used) have LOS problem :(
3063 x = first_x;
3064 y = first_y;
3065
3066 UpdateGroundPositionZ(x, y, z); // update to LOS height if available
3067 */
3068}
3069
3070void WorldObject::GetClosePoint(float& x, float& y, float& z, float size, float distance2d /*= 0*/, float angle /*= 0*/) const
3071{
3072 // angle calculated from current orientation
3073 GetNearPoint(NULL, x, y, z, size, distance2d, GetOrientation() + angle);
3074}
3075
3076void WorldObject::GetNearPosition(Position& pos, float dist, float angle)
3077{
3078 GetPosition(&pos);
3079 MovePosition(pos, dist, angle);
3080}
3081
3082void WorldObject::GetFirstCollisionPosition(Position& pos, float dist, float angle)
3083{
3084 GetPosition(&pos);
3085 MovePositionToFirstCollision(pos, dist, angle);
3086}
3087
3089{
3090 GetPosition(&pos);
3091 MovePosition(pos, radius * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI));
3092}
3093
3094void WorldObject::GetContactPoint(const WorldObject* obj, float& x, float& y, float& z, float distance2d /*= CONTACT_DISTANCE*/) const
3095{
3096 // angle to face `obj` to `this` using distance includes size of `obj`
3097 GetNearPoint(obj, x, y, z, obj->GetObjectSize(), distance2d, GetAngle(obj));
3098}
3099
3104
3105void WorldObject::MovePosition(Position& pos, float dist, float angle)
3106{
3107 angle += GetOrientation();
3108 float destx, desty, destz, ground, floor;
3109 destx = pos.m_positionX + dist * std::cos(angle);
3110 desty = pos.m_positionY + dist * std::sin(angle);
3111
3112 // Prevent invalid coordinates here, position is unchanged
3113 if (!Skyfire::IsValidMapCoord(destx, desty, pos.m_positionZ))
3114 {
3115 SF_LOG_FATAL("misc", "WorldObject::MovePosition: Object (TypeId: %u Entry: %u GUID: %u) has invalid coordinates X: %f and Y: %f were passed!",
3116 uint8(GetTypeId()), GetEntry(), GetGUIDLow(), destx, desty);
3117 return;
3118 }
3119
3120 ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
3121 floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
3122 destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
3123
3124 float step = dist / 10.0f;
3125
3126 for (uint8 j = 0; j < 10; ++j)
3127 {
3128 // do not allow too big z changes
3129 if (fabs(pos.m_positionZ - destz) > 6)
3130 {
3131 destx -= step * std::cos(angle);
3132 desty -= step * std::sin(angle);
3133 ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
3134 floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
3135 destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
3136 }
3137 // we have correct destz now
3138 else
3139 {
3140 pos.Relocate(destx, desty, destz);
3141 break;
3142 }
3143 }
3144
3149}
3150
3151void WorldObject::MovePositionToFirstCollision(Position& pos, float dist, float angle)
3152{
3153 angle += GetOrientation();
3154 float destx, desty, destz, ground, floor;
3155 pos.m_positionZ += 2.0f;
3156 destx = pos.m_positionX + dist * std::cos(angle);
3157 desty = pos.m_positionY + dist * std::sin(angle);
3158
3159 // Prevent invalid coordinates here, position is unchanged
3160 if (!Skyfire::IsValidMapCoord(destx, desty))
3161 {
3162 SF_LOG_FATAL("misc", "WorldObject::MovePositionToFirstCollision invalid coordinates X: %f and Y: %f were passed!", destx, desty);
3163 return;
3164 }
3165
3166 ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
3167 floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
3168 destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
3169
3170 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);
3171
3172 // collision occured
3173 if (col)
3174 {
3175 // move back a bit
3176 destx -= CONTACT_DISTANCE * std::cos(angle);
3177 desty -= CONTACT_DISTANCE * std::sin(angle);
3178 dist = sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
3179 }
3180
3181 // check dynamic collision
3182 col = GetMap()->getObjectHitPos(GetPhaseMask(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
3183
3184 // Collided with a gameobject
3185 if (col)
3186 {
3187 destx -= CONTACT_DISTANCE * std::cos(angle);
3188 desty -= CONTACT_DISTANCE * std::sin(angle);
3189 dist = sqrt((pos.m_positionX - destx) * (pos.m_positionX - destx) + (pos.m_positionY - desty) * (pos.m_positionY - desty));
3190 }
3191
3192 float step = dist / 10.0f;
3193
3194 for (uint8 j = 0; j < 10; ++j)
3195 {
3196 // do not allow too big z changes
3197 if (fabs(pos.m_positionZ - destz) > 6)
3198 {
3199 destx -= step * std::cos(angle);
3200 desty -= step * std::sin(angle);
3201 ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
3202 floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
3203 destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
3204 }
3205 // we have correct destz now
3206 else
3207 {
3208 pos.Relocate(destx, desty, destz);
3209 break;
3210 }
3211 }
3212
3217}
3218
3219void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
3220{
3221 m_phaseMask = newPhaseMask;
3222
3223 if (update && IsInWorld())
3225}
3226
3228{
3229 // Clear all terrain swaps, will be rebuilt below
3230 // Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it
3231 _terrainSwaps.clear();
3232
3233 // Check all applied phases for terrain swap and add it only once
3234 for (uint32 phaseId : _phases)
3235 {
3236 if (std::vector<PhaseInfoStruct> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
3237 {
3238 for (PhaseInfoStruct const& swap : *swaps)
3239 {
3240 // only add terrain swaps for current map
3241 MapEntry const* mapEntry = sMapStore.LookupEntry(swap.id);
3242 if (!mapEntry || mapEntry->rootPhaseMap != int32(GetMapId()))
3243 continue;
3244
3245 if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
3246 _terrainSwaps.insert(swap.id);
3247 }
3248 }
3249 }
3250
3251 // get default terrain swaps, only for current map always
3252 if (std::vector<PhaseInfoStruct> const* mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId()))
3253 for (PhaseInfoStruct const& swap : *mapSwaps)
3254 if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
3255 _terrainSwaps.insert(swap.id);
3256
3257 // online players have a game client with world map display
3260}
3261
3263{
3264 // Clear all world map area swaps, will be rebuilt below
3265 _worldMapSwaps.clear();
3266
3267 // get ALL default terrain swaps, if we are using it (condition is true)
3268 // send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current
3269 TerrainPhaseInfo const& defaults = sObjectMgr->GetDefaultTerrainSwapStore();
3270 for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr)
3271 for (PhaseInfoStruct const& swap : itr->second)
3272 if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap.id))
3273 if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
3274 for (uint32 worldMapAreaId : *uiMapSwaps)
3275 _worldMapSwaps.insert(worldMapAreaId);
3276
3277 // Check all applied phases for world map area swaps
3278 for (uint32 phaseId : _phases)
3279 if (std::vector<PhaseInfoStruct> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
3280 for (PhaseInfoStruct const& swap : *swaps)
3281 if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap.id))
3282 if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
3283 for (uint32 worldMapAreaId : *uiMapSwaps)
3284 _worldMapSwaps.insert(worldMapAreaId);
3285}
3286
3288{
3289 bool updateNeeded = false;
3290 PhaseInfo const& phases = sObjectMgr->GetAreaPhases();
3291 for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
3292 {
3293 uint32 areaId = itr->first;
3294 for (PhaseInfoStruct const& phase : itr->second)
3295 {
3296 if (areaId == GetAreaId())
3297 {
3298 if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
3299 {
3300 // add new phase if condition passed, true if it wasnt added before
3301 bool up = SetPhased(phase.id, false, true);
3302 if (!updateNeeded && up)
3303 updateNeeded = true;
3304 }
3305 else
3306 {
3307 // condition failed, remove phase, true if there was something removed
3308 bool up = SetPhased(phase.id, false, false);
3309 if (!updateNeeded && up)
3310 updateNeeded = true;
3311 }
3312 }
3313 }
3314 }
3315
3316 // do not remove a phase if it would be removed by an area but we have the same phase from an aura
3317 if (Unit* unit = ToUnit())
3318 {
3319 Unit::AuraEffectList const& auraPhaseList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE);
3320 for (Unit::AuraEffectList::const_iterator itr = auraPhaseList.begin(); itr != auraPhaseList.end(); ++itr)
3321 {
3322 uint32 phase = uint32((*itr)->GetMiscValueB());
3323 bool up = SetPhased(phase, false, true);
3324 if (!updateNeeded && up)
3325 updateNeeded = true;
3326 }
3327 Unit::AuraEffectList const& auraPhaseGroupList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP);
3328 for (Unit::AuraEffectList::const_iterator itr = auraPhaseGroupList.begin(); itr != auraPhaseGroupList.end(); ++itr)
3329 {
3330 bool up = false;
3331 uint32 phaseGroup = uint32((*itr)->GetMiscValueB());
3332 std::set<uint32> const& phases = GetPhasesForGroup(phaseGroup);
3333 for (uint32 phase : phases)
3334 up = SetPhased(phase, false, true);
3335 if (!updateNeeded && up)
3336 updateNeeded = true;
3337 }
3338 }
3339
3340 // only update visibility and send packets if there was a change in the phase list
3341
3342 if (updateNeeded && GetTypeId() == TypeID::TYPEID_PLAYER && IsInWorld())
3344
3345 // only update visibilty once, to prevent objects appearing for a moment while adding in multiple phases
3346 if (updateNeeded && IsInWorld())
3348}
3350{
3351 return _phases.find(phase) != _phases.end();
3352}
3353bool WorldObject::SetPhased(uint32 id, bool update, bool apply)
3354{
3355 if (id)
3356 {
3357 if (apply)
3358 {
3359 if (HasPhaseList(id)) // do not run the updates if we are already in this phase
3360 return false;
3361 _phases.insert(id);
3362 }
3363 else
3364 {
3365 if (std::vector<PhaseInfoStruct> const* phases = sObjectMgr->GetPhasesForArea(GetAreaId()))
3366 for (PhaseInfoStruct const& phase : *phases)
3367 if (id == phase.id)
3368 if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
3369 return false;
3370
3371 if (!HasPhaseList(id)) // do not run the updates if we are not in this phase
3372 return false;
3373 _phases.erase(id);
3374 }
3375 }
3377
3378 if (update && IsInWorld())
3380 return true;
3381}
3382
3384{
3385 _phases.clear();
3386
3388
3389 if (update && IsInWorld())
3391}
3392
3394{
3395 // PhaseId 169 is the default fallback phase
3396 if (_phases.empty() && obj->GetPhases().empty())
3397 return true;
3398
3399 if (_phases.empty() && obj->IsPhased(169))
3400 return true;
3401
3402 if (obj->GetPhases().empty() && IsPhased(169))
3403 return true;
3404
3405 if (GetTypeId() == TypeID::TYPEID_PLAYER && ToPlayer()->IsGameMaster())
3406 return true;
3407
3408 return Skyfire::Containers::Intersects(_phases.begin(), _phases.end(), obj->GetPhases().begin(), obj->GetPhases().end());
3409}
3410
3411//Temp Speshul Tactics
3413{
3414 return IsPhased(obj);
3415}
3416
3418{
3419 ObjectGuid TargetGUID = target->GetGUID();
3420 ObjectGuid SourceGUID = GetGUID();
3421
3422 WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 8 + 8 + 4);
3423 data.WriteGuidMask(SourceGUID, 5);
3424 data.WriteGuidMask(TargetGUID, 7, 0, 3);
3425 data.WriteGuidMask(SourceGUID, 1);
3426 data.WriteGuidMask(TargetGUID, 4);
3427 data.WriteGuidMask(SourceGUID, 7, 2, 4, 3);
3428 data.WriteGuidMask(TargetGUID, 5, 1, 6, 2);
3429 data.WriteGuidMask(SourceGUID, 6, 0);
3430
3431 data.WriteGuidBytes(TargetGUID, 6, 2);
3432 data.WriteGuidBytes(SourceGUID, 2, 5);
3433 data.WriteGuidBytes(TargetGUID, 7, 5, 3, 1);
3434 data.WriteGuidBytes(SourceGUID, 3, 1);
3435 data << uint32(sound_id);
3436 data.WriteGuidBytes(TargetGUID, 4);
3437 data.WriteGuidBytes(SourceGUID, 4, 7, 0, 6);
3438 data.WriteGuidBytes(TargetGUID, 0);
3439 target->SendDirectMessage(&data);
3440}
3441
3442void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/)
3443{
3445 data << uint32(sound_id);
3446 data << uint64(GetGUID());
3447 if (target)
3448 target->SendDirectMessage(&data);
3449 else
3450 SendMessageToSet(&data, true);
3451}
3452
3454{
3455 if (!IsInWorld())
3456 return;
3457
3458 std::list<Player*> targets;
3462 for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
3463 {
3464 Player* player = (*iter);
3465
3466 if (player == this)
3467 continue;
3468
3469 if (!player->HaveAtClient(this))
3470 continue;
3471
3472 if (isType(TYPEMASK_UNIT) && ((Unit*)this)->GetCharmerGUID() == player->GetGUID())
3473 continue;
3474
3475 DestroyForPlayer(player);
3476 player->m_clientGUIDs.erase(GetGUID());
3477 }
3478}
3479
3481{
3482 //updates object's visibility for nearby players
3483 Skyfire::VisibleChangesNotifier notifier(*this);
3485}
3486
3488{
3491 std::set<uint64> plr_list;
3494 {
3495 Player* source = NULL;
3496 for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
3497 {
3498 source = iter->GetSource();
3499
3500 BuildPacket(source);
3501
3502 if (!source->GetSharedVisionList().empty())
3503 {
3504 SharedVisionList::const_iterator it = source->GetSharedVisionList().begin();
3505 for (; it != source->GetSharedVisionList().end(); ++it)
3506 BuildPacket(*it);
3507 }
3508 }
3509 }
3510
3512 {
3513 Creature* source = NULL;
3514 for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
3515 {
3516 source = iter->GetSource();
3517 if (!source->GetSharedVisionList().empty())
3518 {
3519 SharedVisionList::const_iterator it = source->GetSharedVisionList().begin();
3520 for (; it != source->GetSharedVisionList().end(); ++it)
3521 BuildPacket(*it);
3522 }
3523 }
3524 }
3525
3527 {
3528 DynamicObject* source = NULL;
3529 for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
3530 {
3531 source = iter->GetSource();
3532 uint64 guid = source->GetCasterGUID();
3533
3534 if (IS_PLAYER_GUID(guid))
3535 {
3536 //Caster may be NULL if DynObj is in removelist
3537 if (Player* caster = ObjectAccessor::FindPlayer(guid))
3538 if (caster->GetUInt64Value(PLAYER_FIELD_FARSIGHT_OBJECT) == source->GetGUID())
3539 BuildPacket(caster);
3540 }
3541 }
3542 }
3543
3544 void BuildPacket(Player* player)
3545 {
3546 // Only send update once to a player
3547 if (plr_list.find(player->GetGUID()) == plr_list.end() && player->HaveAtClient(&i_object))
3548 {
3549 i_object.BuildFieldsUpdate(player, i_updateDatas);
3550 plr_list.insert(player->GetGUID());
3551 }
3552 }
3553
3554 template<class SKIP> void Visit(GridRefManager<SKIP>&) { }
3555};
3556
3558{
3560 Cell cell(p);
3561 cell.SetNoCreate();
3562 WorldObjectChangeAccumulator notifier(*this, data_map);
3564 Map& map = *GetMap();
3565 //we must build packets for all visible players
3566 cell.Visit(p, player_notifier, map, *this, GetVisibilityRange());
3567
3568 ClearUpdateMask(false);
3569}
3570
3572{
3573 if (GetTransport())
3574 return GetTransport()->GetGUID();
3575 return 0;
3576}
#define sBattlefieldMgr
LocaleConstant
Definition Common.h:138
#define M_PI
Definition Common.h:192
#define sConditionMgr
std::set< uint32 > const & GetPhasesForGroup(uint32 group)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
std::int32_t int32
Definition Define.h:73
#define UI64FMTD
Definition Define.h:64
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::int8_t int8
Definition Define.h:75
std::uint64_t uint64
Definition Define.h:76
std::uint16_t uint16
Definition Define.h:78
static constexpr TypeID TYPEID_OBJECT
#define ASSERT
Definition Errors.h:29
@ GO_STATE_READY
Definition GameObject.h:577
GridRefManager< DynamicObject > DynamicObjectMapType
Definition GridDefines.h:52
GridRefManager< Creature > CreatureMapType
Definition GridDefines.h:51
GridRefManager< Player > PlayerMapType
Definition GridDefines.h:54
TypeMapContainer< AllWorldObjectTypes > WorldTypeMapContainer
Definition GridDefines.h:72
TypeMapContainer< AllGridObjectTypes > GridTypeMapContainer
Definition GridDefines.h:71
CoordPair< TOTAL_NUMBER_OF_CELLS_PER_MAP > CellCoord
#define SF_LOG_FATAL(filterType__,...)
Definition Log.h:146
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define MAX_HEIGHT
Definition Map.h:141
#define INVALID_HEIGHT
Definition Map.h:142
TypeID GuidHigh2TypeId(uint32 guid_hi)
Definition Object.cpp:44
ByteBuffer & operator>>(ByteBuffer &buf, Position::PositionXYZOStreamer const &streamer)
Definition Object.cpp:1448
ByteBuffer & operator<<(ByteBuffer &buf, Position::PositionXYZStreamer const &streamer)
Definition Object.cpp:1455
@ PHASEMASK_NORMAL
Definition Object.h:80
TypeID
Definition Object.h:50
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_GAMEOBJECT
Definition Object.h:56
@ TYPEID_DYNAMICOBJECT
Definition Object.h:57
@ TYPEID_UNIT
Definition Object.h:54
@ TYPEID_ITEM
Definition Object.h:52
@ TYPEID_OBJECT
Definition Object.h:51
@ TYPEID_CORPSE
Definition Object.h:58
@ NUM_CLIENT_OBJECT_TYPES
Definition Object.h:61
@ TYPEID_AREATRIGGER
Definition Object.h:59
@ TYPEID_CONTAINER
Definition Object.h:53
#define MAX_VISIBILITY_DISTANCE
Definition Object.h:23
UNORDERED_MAP< Player *, UpdateData > UpdateDataMapType
Definition Object.h:107
TempSummonType
Definition Object.h:67
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:70
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:74
#define SIGHT_RANGE_UNIT
Definition Object.h:24
#define CONTACT_DISTANCE
Definition Object.h:20
#define DEFAULT_WORLD_OBJECT_SIZE
Definition Object.h:29
#define DEFAULT_VISIBILITY_INSTANCE
Definition Object.h:26
@ TYPEMASK_OBJECT
Definition Object.h:37
@ TYPEMASK_ITEM
Definition Object.h:38
@ TYPEMASK_UNIT
Definition Object.h:40
@ TYPEMASK_GAMEOBJECT
Definition Object.h:42
@ TYPEMASK_PLAYER
Definition Object.h:41
#define sObjectAccessor
uint32 PAIR64_LOPART(uint64 x)
HighGuid
@ HIGHGUID_PET
@ HIGHGUID_AREATRIGGER
@ HIGHGUID_DYNAMICOBJECT
@ HIGHGUID_GAMEOBJECT
@ HIGHGUID_TRANSPORT
@ HIGHGUID_CORPSE
@ HIGHGUID_PLAYER
@ HIGHGUID_MO_TRANSPORT
@ HIGHGUID_UNIT
@ HIGHGUID_ITEM
@ HIGHGUID_VEHICLE
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
uint32 PAIR64_HIPART(uint64 x)
bool IS_PLAYER_GUID(uint64 guid)
UNORDERED_MAP< uint32, std::vector< PhaseInfoStruct > > PhaseInfo
Definition ObjectMgr.h:707
#define sObjectMgr
Definition ObjectMgr.h:1617
UNORDERED_MAP< uint32, std::vector< PhaseInfoStruct > > TerrainPhaseInfo
Definition ObjectMgr.h:705
#define sOutdoorPvPMgr
@ SERVERSIDE_VISIBILITY_GM
@ SERVERSIDE_VISIBILITY_GHOST
GameobjectTypes
@ GAMEOBJECT_TYPE_SPELL_FOCUS
@ GAMEOBJECT_TYPE_DUEL_ARBITER
@ GAMEOBJECT_TYPE_TRANSPORT
@ GAMEOBJECT_TYPE_TRAP
@ GAMEOBJECT_TYPE_FLAGDROP
@ GAMEOBJECT_TYPE_FLAGSTAND
ChatMsg
@ CHAT_MSG_MONSTER_SAY
@ CHAT_MSG_MONSTER_EMOTE
@ CHAT_MSG_RAID_BOSS_WHISPER
@ CHAT_MSG_RAID_BOSS_EMOTE
@ CHAT_MSG_MONSTER_YELL
@ CHAT_MSG_MONSTER_WHISPER
StealthType
@ TOTAL_STEALTH_TYPES
Language
InvisibilityType
@ TOTAL_INVISIBILITY_TYPES
@ UNIT_DYNFLAG_SPECIALINFO
@ SUMMON_TYPE_VEHICLE2
@ SUMMON_TYPE_LIGHTWELL
@ SUMMON_TYPE_MINION
@ SUMMON_TYPE_GUARDIAN
@ SUMMON_TYPE_STATUE
@ SUMMON_TYPE_TOTEM
@ SUMMON_TYPE_VEHICLE
@ SUMMON_TYPE_MINIPET
@ SUMMON_TYPE_GUARDIAN2
@ GHOST_VISIBILITY_ALIVE
@ GHOST_VISIBILITY_GHOST
@ SUMMON_CATEGORY_PET
@ SUMMON_CATEGORY_VEHICLE
@ SUMMON_CATEGORY_ALLY
@ SUMMON_CATEGORY_PUPPET
@ SUMMON_CATEGORY_WILD
@ SUMMON_CATEGORY_UNK
@ SPELL_AURA_EMPATHY
@ SPELL_AURA_PHASE_GROUP
@ SPELL_AURA_WATER_WALK
@ SPELL_AURA_PHASE
@ SPELL_AURA_DETECT_STEALTH
uint32 getMSTime()
Definition Timer.h:12
MovementFlags
Definition Unit.h:721
@ MOVEMENTFLAG_MASK_CREATURE_ALLOWED
Definition Unit.h:768
@ MOVEMENTFLAG_FLYING
Definition Unit.h:747
@ MOVEMENTFLAG_FALLING
Definition Unit.h:734
@ MOVEMENTFLAG_SWIMMING
Definition Unit.h:743
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition Unit.h:748
@ UNIT_MASK_PUPPET
Definition Unit.h:811
@ UNIT_MASK_TOTEM
Definition Unit.h:808
@ UNIT_MASK_SUMMON
Definition Unit.h:805
@ UNIT_MASK_GUARDIAN
Definition Unit.h:807
@ UNIT_MASK_MINION
Definition Unit.h:806
#define WORLD_TRIGGER
Definition Unit.h:20
#define MAX_PLAYER_STEALTH_DETECT_RANGE
Definition Unit.h:1362
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition Unit.h:788
@ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT
Definition Unit.h:797
@ MOVE_FLIGHT
Definition Unit.h:561
@ MOVE_SWIM
Definition Unit.h:558
@ MOVE_TURN_RATE
Definition Unit.h:560
@ MOVE_FLIGHT_BACK
Definition Unit.h:562
@ MOVE_SWIM_BACK
Definition Unit.h:559
@ MOVE_RUN
Definition Unit.h:556
@ MOVE_PITCH_RATE
Definition Unit.h:563
@ MOVE_RUN_BACK
Definition Unit.h:557
@ MOVE_WALK
Definition Unit.h:555
@ UPDATETYPE_VALUES
Definition UpdateData.h:16
@ UPDATETYPE_CREATE_OBJECT
Definition UpdateData.h:17
@ UPDATETYPE_CREATE_OBJECT2
Definition UpdateData.h:18
@ UPDATEFLAG_LIVING
Definition UpdateData.h:30
@ UPDATEFLAG_ROTATION
Definition UpdateData.h:34
@ UPDATEFLAG_VEHICLE
Definition UpdateData.h:32
@ UPDATEFLAG_TRANSPORT
Definition UpdateData.h:26
@ UPDATEFLAG_NONE
Definition UpdateData.h:24
@ UPDATEFLAG_SELF
Definition UpdateData.h:25
@ UPDATEFLAG_STATIONARY_POSITION
Definition UpdateData.h:31
@ UPDATEFLAG_HAS_TARGET
Definition UpdateData.h:27
@ UPDATEFLAG_GO_TRANSPORT_POSITION
Definition UpdateData.h:33
uint32 UnitUpdateFieldFlags[PLAYER_END]
uint32 CorpseUpdateFieldFlags[CORPSE_END]
uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END]
uint32 ItemUpdateFieldFlags[CONTAINER_END]
uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END]
uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END]
@ UF_FLAG_VIEWER_DEPENDENT
@ UF_FLAG_SPECIAL_INFO
@ UF_FLAG_ITEM_OWNER
@ UF_FLAG_PUBLIC
@ UF_FLAG_OWNER
@ UF_FLAG_PRIVATE
@ UF_FLAG_PARTY_MEMBER
@ UF_FLAG_URGENT
@ UNIT_FIELD_COMBAT_REACH
@ UNIT_FIELD_CREATED_BY_SPELL
@ OBJECT_FIELD_GUID
@ OBJECT_FIELD_TYPE
@ OBJECT_FIELD_DYNAMIC_FLAGS
@ PLAYER_DYNAMIC_FIELD_RESEARCH_SITE_PROGRESS
@ PLAYER_DYNAMIC_FIELD_RESERACH_SITE
@ PLAYER_FIELD_FARSIGHT_OBJECT
double rand_norm(void)
Definition Util.cpp:50
void ApplyPercentModFloatVar(float &var, float val, bool apply)
Definition Util.h:94
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void append(T value)
Definition ByteBuffer.h:147
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const &message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="", std::string const &addonPrefix="")
Definition Chat.cpp:580
void SetHomePosition(float x, float y, float z, float o)
Definition Creature.h:626
float m_SightDistance
Definition Creature.h:660
bool CanSwim() const
Definition Creature.h:457
bool AIM_Initialize(CreatureAI *ai=NULL)
Definition Creature.cpp:702
bool Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data=NULL)
Definition Creature.cpp:740
uint64 GetCasterGUID() const
T_FLAGS GetFlags() const
Definition Object.h:573
T_VALUES GetValue(FLAG_TYPE flag) const
Definition Object.h:578
Unit * GetOwner() const
GameObjectValue const * GetGOValue() const
Definition GameObject.h:645
bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit=0)
void SetRespawnTime(int32 respawn)
Definition GameObject.h:699
void SetSpawnedByDefault(bool b)
Definition GameObject.h:712
GameobjectTypes GetGoType() const
Definition GameObject.h:719
bool SetPhased(uint32 id, bool update, bool apply) OVERRIDE
Transport * ToTransport()
Definition GameObject.h:833
LinkedListHead::Iterator< GridReference< Player > > iterator
iterator begin()
Definition Item.h:202
Definition Map.h:238
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
Definition Map.cpp:2231
bool IsBattlegroundOrArena() const
Definition Map.h:378
void RemoveFromActive(T *obj)
Definition Map.cpp:2610
void AddObjectToRemoveList(WorldObject *obj)
Definition Map.cpp:2410
uint32 GetZoneId(float x, float y, float z) const
Definition Map.h:335
bool AddToMap(T *)
Definition Map.cpp:504
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1959
bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist)
Definition Map.cpp:2237
uint32 GetAreaId(float x, float y, float z) const
Definition Map.h:330
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=NULL)
Definition Object.cpp:2675
TempSummon * SummonCreature(uint32 entry, Position const &pos, SummonPropertiesEntry const *properties=NULL, uint32 duration=0, Unit *summoner=NULL, uint32 spellId=0, uint32 vehId=0)
Definition Object.cpp:2564
float GetWaterOrGroundLevel(float x, float y, float z, float *ground=NULL, bool swim=false) const
Definition Map.cpp:1941
void AddToActive(T *obj)
Definition Map.cpp:2569
float GetVisibilityRange() const
Definition Map.h:267
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid, float x, float y, float z) const
Definition Map.h:340
uint32 GetInstanceId() const
Definition Map.h:357
uint32 GetId(void) const
Definition Map.h:300
void AddObjectToSwitchList(WorldObject *obj, bool on)
Definition Map.cpp:2424
bool IsInstance() const
Definition Map.h:368
static void WriteCreateData(MoveSpline const &moveSpline, ByteBuffer &data)
static void WriteFacingTargetPart(MoveSpline const &moveSpline, ByteBuffer &data)
static void WriteCreateBits(MoveSpline const &moveSpline, ByteBuffer &data)
static Player * FindPlayer(uint64)
void ApplyModSignedFloatValue(uint16 index, float val, bool apply)
Definition Object.cpp:1238
void UpdateUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1071
void ToggleFlag64(uint16 index, uint64 flag)
Definition Object.cpp:1397
Corpse * ToCorpse()
Definition Object.h:216
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition Object.cpp:343
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition Object.cpp:1158
int32 * m_int32Values
Definition Object.h:249
void BuildFieldsUpdate(Player *, UpdateDataMapType &) const
Definition Object.cpp:932
uint16 m_objectType
Definition Object.h:242
ObjectGuid GetObjectGUID() const
Definition Object.h:123
int32 GetInt32Value(uint16 index) const
Definition Object.cpp:319
void ApplyModFlag64(uint16 index, uint64 flag, bool apply)
Definition Object.cpp:1411
void SetInt32Value(uint16 index, int32 value)
Definition Object.cpp:1021
uint64 GetGUID() const
Definition Object.h:119
DynamicObject * ToDynObject()
Definition Object.h:219
void SetUInt16Value(uint16 index, uint8 offset, uint16 value)
Definition Object.cpp:1182
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
Object()
Definition Object.cpp:64
void _LoadIntoDataField(std::string const &data, uint32 startOffset, uint32 count)
Definition Object.cpp:1004
uint16 GetUInt16Value(uint16 index, uint8 offset) const
Definition Object.cpp:350
virtual void DestroyForPlayer(Player *target, bool onDeath=false) const
Definition Object.cpp:287
uint32 GetGUIDLow() const
Definition Object.h:120
virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, Player *target) const
Definition Object.cpp:804
void ApplyModInt32Value(uint16 index, int32 val, bool apply)
Definition Object.cpp:1231
uint32 GetUpdateFieldData(Player const *target, uint32 *&flags) const
Definition Object.cpp:946
std::vector< uint32 * > m_dynamicTab
Definition Object.h:239
void ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
Definition Object.cpp:1252
UpdateMask _changesMask
Definition Object.h:254
void SendDestroyObject(Player *target, ObjectGuid Guid, bool onDeath=false) const
Definition Object.cpp:306
TypeID GetTypeId() const
Definition Object.h:131
uint32 * m_uint32Values
Definition Object.h:250
virtual void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition Object.cpp:172
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
Definition Object.cpp:129
bool RemoveUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1119
bool isType(uint16 mask) const
Definition Object.h:132
uint16 m_valuesCount
Definition Object.h:256
void _InitValues()
Definition Object.cpp:113
void BuildMovementUpdate(ByteBuffer *data, uint16 flags) const
Definition Object.cpp:363
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
void ApplyModUInt32Value(uint16 index, int32 val, bool apply)
Definition Object.cpp:1222
float GetFloatValue(uint16 index) const
Definition Object.cpp:337
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:1317
void ClearUpdateMask(bool remove)
Definition Object.cpp:917
uint32 GetDynamicUInt32Value(uint32 tab, uint16 index) const
Definition Object.cpp:357
void BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer *data, Player *target) const
Definition Object.cpp:832
uint16 m_fieldNotifyFlags
Definition Object.h:258
GameObject * ToGameObject()
Definition Object.h:213
void SetFlag64(uint16 index, uint64 newFlag)
Definition Object.cpp:1383
const ByteBuffer & GetPackGUID() const
Definition Object.h:124
uint32 GetEntry() const
Definition Object.h:125
uint64 GetUInt64Value(uint16 index) const
Definition Object.cpp:331
bool PrintIndexError(uint32 index, bool set) const
Definition Object.cpp:1416
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition Object.cpp:270
Creature * ToCreature()
Definition Object.h:207
void RemoveFlag64(uint16 index, uint64 oldFlag)
Definition Object.cpp:1390
void SetFloatValue(uint16 index, float value)
Definition Object.cpp:1141
void SetDynamicUInt32Value(uint32 tab, uint16 index, uint32 value)
Definition Object.cpp:1055
void SetStatFloatValue(uint16 index, float value)
Definition Object.cpp:1206
std::vector< bool * > m_dynamicChange
Definition Object.h:240
virtual void AddToWorld()
Definition Object.cpp:148
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1345
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
std::string _ConcatFields(uint16 startIndex, uint16 size) const
Definition Object.cpp:140
virtual void RemoveFromWorld()
Definition Object.cpp:161
bool m_inWorld
Definition Object.h:263
uint32 GetGUIDHigh() const
Definition Object.h:122
float * m_floatValues
Definition Object.h:251
void BuildOutOfRangeUpdateBlock(UpdateData *data) const
Definition Object.cpp:282
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition Object.cpp:1376
void SendUpdateToPlayer(Player *player)
Definition Object.cpp:259
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
ByteBuffer m_PackGUID
Definition Object.h:265
uint16 m_updateFlag
Definition Object.h:245
void ToggleFlag(uint16 index, uint32 flag)
Definition Object.cpp:1301
virtual ~Object()
Definition Object.cpp:85
bool HasFlag64(uint16 index, uint64 flag) const
Definition Object.cpp:1405
TypeID m_objectTypeId
Definition Object.h:244
void ApplyPercentModFloatValue(uint16 index, float val, bool apply)
Definition Object.cpp:1245
void SetStatInt32Value(uint16 index, int32 value)
Definition Object.cpp:1214
bool m_objectUpdated
Definition Object.h:260
void SetUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1079
void ToggleByteFlag(uint16 index, uint8 offset, uint8 flag)
Definition Object.cpp:1368
Unit * ToUnit()
Definition Object.h:210
void ForceValuesUpdateAtIndex(uint32)
Definition Object.cpp:2328
bool AddUInt64Value(uint16 index, uint64 value)
Definition Object.cpp:1097
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition Object.cpp:1322
uint32 GetTeam() const
Definition Player.h:2527
bool IsInSameRaidWith(Player const *p) const
Definition Player.cpp:3030
ClientGUIDs m_clientGUIDs
Definition Player.h:2857
void SendDirectMessage(WorldPacket *data)
Definition Player.cpp:6904
bool HaveAtClient(WorldObject const *u) const
Definition Player.cpp:18066
WorldSession * GetSession() const
Definition Player.h:2417
Battleground * GetBattleground() const
Definition Player.cpp:19212
MonsterChatBuilder(WorldObject const *obj, ChatMsg msgtype, int32 textId, Language language, WorldObject const *target)
Definition Object.cpp:2343
void operator()(WorldPacket &data, LocaleConstant loc_idx)
Definition Object.cpp:2346
WorldObject const * i_target
Definition Object.cpp:2359
WorldObject const * i_object
Definition Object.cpp:2355
void operator()(WorldPacket &data, LocaleConstant loc_idx)
Definition Object.cpp:2368
MonsterCustomChatBuilder(WorldObject const *obj, ChatMsg msgtype, const char *text, Language language, WorldObject const *target)
Definition Object.cpp:2365
WorldObject const * i_object
Definition Object.cpp:2375
WorldObject const * i_target
Definition Object.cpp:2379
virtual void InitSummon()
virtual void InitStats(uint32 lifetime)
size_type size() const
Definition Util.h:46
Definition Totem.h:19
Definition Unit.h:1367
void setFaction(uint32 faction)
Definition Unit.h:1699
uint32 GetUnitMovementFlags() const
Definition Unit.h:2632
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:4313
uint32 GetMovementCounter() const
Definition Unit.h:2849
bool SetPhased(uint32 id, bool update, bool apply) OVERRIDE
Definition Unit.cpp:7516
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:2355
float GetPositionZMinusOffset() const
Definition Unit.cpp:6660
bool IsSplineEnabled() const
Definition Unit.cpp:9355
Unit * GetCharmerOrOwner() const
Definition Unit.cpp:2419
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:1671
float GetCombatReach() const
Definition Unit.h:1445
SharedVisionList const & GetSharedVisionList()
Definition Unit.h:2157
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:2628
uint16 GetExtraUnitMovementFlags() const
Definition Unit.h:2653
uint16 HasExtraUnitMovementFlag(uint16 f) const
Definition Unit.h:2649
Unit * GetVictim() const
Definition Unit.h:1468
std::unique_ptr< Movement::MoveSpline > movespline
Definition Unit.h:2837
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
void SetLevel(uint8 lvl)
Definition Unit.cpp:5150
Vehicle * GetVehicleKit() const
Definition Unit.h:2739
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const
void AddUpdateBlock(const ByteBuffer &block)
void AddOutOfRangeGUID(std::set< uint64 > &guids)
bool BuildPacket(WorldPacket *packet)
uint32 GetBlockCount() const
Definition UpdateMask.h:51
void SetCount(uint32 valuesCount)
Definition UpdateMask.h:54
void SetBit(uint32 index)
Definition UpdateMask.h:34
void AppendToPacket(ByteBuffer *data)
Definition UpdateMask.h:38
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
static IVMapManager * createOrGetVMapManager()
VehicleEntry const * GetVehicleInfo() const
Definition Vehicle.h:39
WorldLocation(uint32 _mapid=MAPID_INVALID, float _x=0, float _y=0, float _z=0, float _o=0)
Definition Object.h:536
uint32 GetMapId() const
Definition Object.h:546
uint32 m_mapId
Definition Object.h:548
bool isInFront(WorldObject const *target, float arc=M_PI) const
Definition Object.cpp:1940
int8 GetTransSeat() const
Definition Object.h:803
bool IsPhased(WorldObject const *obj) const
Definition Object.cpp:3393
virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self)
Definition Object.cpp:2491
virtual void SetPhaseMask(uint32 newPhaseMask, bool update)
Definition Object.cpp:3219
void _Create(uint32 guidlow, HighGuid guidhigh, uint32 phaseMask)
Definition Object.cpp:1581
uint32 GetPhaseMask() const
Definition Object.h:643
bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const
Definition Object.cpp:1820
bool IsWithinDist2d(float x, float y, float dist) const
Definition Object.cpp:1720
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1710
Map * GetMap() const
Definition Object.h:740
virtual void ResetMap()
Definition Object.cpp:2532
bool CanDetectStealthOf(WorldObject const *obj) const
Definition Object.cpp:2240
std::string m_name
Definition Object.h:815
InstanceScript * GetInstanceScript()
Definition Object.cpp:1612
virtual void RemoveFromWorld()
Definition Object.cpp:1587
std::set< uint32 > const & GetTerrainSwaps() const
Definition Object.h:649
Map * FindMap() const
Definition Object.h:741
bool IsWorldObject() const
Definition Object.cpp:1531
std::set< uint32 > _worldMapSwaps
Definition Object.h:842
void UpdateAreaPhase()
Definition Object.cpp:3287
virtual float GetStationaryO() const
Definition Object.h:812
uint16 m_executed_notifies
Definition Object.h:845
uint16 m_notifyflags
Definition Object.h:844
virtual ~WorldObject()
Definition Object.cpp:70
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1735
bool IsWithinLOSInMap(WorldObject const *obj) const
Definition Object.cpp:1656
bool IsInRange2d(float x, float y, float minRange, float maxRange) const
Definition Object.cpp:1800
Creature * SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI *(*GetAI)(Creature *)=NULL)
Definition Object.cpp:2762
uint32 m_InstanceId
Definition Object.h:838
virtual bool IsNeverVisible() const
Definition Object.h:829
virtual bool IsInvisibleDueToDespawn() const
Definition Object.h:831
void GetGameObjectListWithEntryInGrid(std::list< GameObject * > &lList, uint32 uiEntry, float fMaxSearchRange) const
Definition Object.cpp:2828
virtual bool IsAlwaysDetectableFor(WorldObject const *) const
Definition Object.h:833
bool HasPhaseList(uint32 phase)
Definition Object.cpp:3349
float GetGridActivationRange() const
Definition Object.cpp:2054
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition Object.cpp:2819
std::set< uint32 > const & GetPhases() const
Definition Object.h:647
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibility
Definition Object.h:729
GameObject * FindNearestGameObject(uint32 entry, float range) const
Definition Object.cpp:2810
void SetWorldObject(bool apply)
Definition Object.cpp:1523
void RebuildWorldMapAreaSwaps()
Definition Object.cpp:3262
void SendObjectDeSpawnAnim(uint64 guid)
Definition Object.cpp:2503
void RebuildTerrainSwaps()
Definition Object.cpp:3227
virtual bool SetPhased(uint32 id, bool update, bool apply)
Definition Object.cpp:3353
float GetTransOffsetX() const
Definition Object.h:798
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:3151
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibilityDetect
Definition Object.h:730
void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const
Definition Object.cpp:2936
bool isActiveObject() const
Definition Object.h:776
bool IsSelfOrInSameMap(WorldObject const *obj) const
Definition Object.cpp:1696
void SetZoneScript()
Definition Object.cpp:2687
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1752
void GetRandomNearPosition(Position &pos, float radius)
Definition Object.cpp:3088
void setActive(bool isActiveObject)
Definition Object.cpp:1542
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1684
ZoneScript * m_zoneScript
Definition Object.h:818
float GetTransOffsetY() const
Definition Object.h:799
void GetPlayerListInGrid(std::list< Player * > &lList, float fMaxSearchRange) const
Definition Object.cpp:2854
virtual void SetMap(Map *map)
Definition Object.cpp:2514
void SendPlaySound(uint32 Sound, bool OnlySelf)
Definition Object.cpp:2300
virtual float GetStationaryX() const
Definition Object.h:809
float GetTransOffsetZ() const
Definition Object.h:800
virtual bool IsAlwaysVisibleFor(WorldObject const *) const
Definition Object.h:830
void BuildUpdate(UpdateDataMapType &)
Definition Object.cpp:3557
void GetFirstCollisionPosition(Position &pos, float dist, float angle)
Definition Object.cpp:3082
void VisitNearbyObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:782
void AddObjectToRemoveList()
Definition Object.cpp:2550
std::set< uint32 > const & GetWorldMapSwaps() const
Definition Object.h:650
std::set< uint32 > _terrainSwaps
Definition Object.h:841
void VisitNearbyGridObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:783
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const
Definition Object.cpp:2945
bool InSamePhase(WorldObject const *obj) const
Definition Object.cpp:3412
WorldObject(bool isWorldObject)
Definition Object.cpp:1514
float GetSightRange(WorldObject const *target=NULL) const
Definition Object.cpp:2078
void GetContactPoint(WorldObject const *obj, float &x, float &y, float &z, float distance2d=CONTACT_DISTANCE) const
Definition Object.cpp:3094
bool CanDetectInvisibilityOf(WorldObject const *obj) const
Definition Object.cpp:2216
uint32 GetTransTime() const
Definition Object.h:802
bool IsWithinLOS(float x, float y, float z) const
Definition Object.cpp:1740
uint32 m_phaseMask
Definition Object.h:839
void DestroyForNearbyPlayers()
Definition Object.cpp:3453
Transport * GetTransport() const
Definition Object.h:797
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition Object.cpp:1985
void GetCreatureListWithEntryInGrid(std::list< Creature * > &lList, uint32 uiEntry, float fMaxSearchRange) const
Definition Object.cpp:2841
void MonsterWhisper(const char *text, Player const *target, bool IsBossWhisper=false)
Definition Object.cpp:2461
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealthDetect
Definition Object.h:727
virtual bool _IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D) const
Definition Object.cpp:1626
void MonsterSay(const char *text, Language language, WorldObject const *target)
Definition Object.cpp:2383
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2801
bool m_isActive
Definition Object.h:816
void UpdateGroundPositionZ(float x, float y, float &z) const
Definition Object.cpp:1978
void MonsterTextEmote(const char *text, WorldObject const *target, bool IsBossEmote=false)
Definition Object.cpp:2440
void ClearPhases(bool update=false)
Definition Object.cpp:3383
const bool m_isWorldObject
Definition Object.h:817
bool isInBack(WorldObject const *target, float arc=M_PI) const
Definition Object.cpp:1945
void VisitNearbyWorldObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:784
Map const * GetBaseMap() const
Definition Object.cpp:2544
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:2729
bool IsInRange(WorldObject const *obj, float minRange, float maxRange, bool is3D=true) const
Definition Object.cpp:1775
void GetClosePoint(float &x, float &y, float &z, float size, float distance2d=0, float angle=0) const
Definition Object.cpp:3070
void PlayDistanceSound(uint32 sound_id, Player *target)
Definition Object.cpp:3417
float GetVisibilityRange() const
Definition Object.cpp:2070
void MonsterYell(const char *text, Language language, WorldObject const *target)
Definition Object.cpp:2411
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealth
Definition Object.h:726
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibilityDetect
Definition Object.h:733
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1666
bool IsInBetween(WorldObject const *obj1, WorldObject const *obj2, float size=0) const
Definition Object.cpp:1920
uint32 GetAreaId() const
Definition Object.cpp:1602
float GetTransOffsetO() const
Definition Object.h:801
void GetNearPosition(Position &pos, float dist, float angle)
Definition Object.cpp:3076
bool CanNeverSee(WorldObject const *obj) const
Definition Object.cpp:2190
void SummonCreatureGroup(uint8 group, std::list< TempSummon * > *list=NULL)
Definition Object.cpp:2787
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true) const
Definition Object.cpp:1730
uint32 GetZoneId() const
Definition Object.cpp:1597
MovementInfo m_movementInfo
Definition Object.h:807
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition Object.cpp:2485
FlaggedValuesArray32< int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES > m_serverSideVisibility
Definition Object.h:732
float GetDistanceZ(WorldObject const *obj) const
Definition Object.cpp:1618
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:1607
float GetObjectSize() const
Definition Object.cpp:3100
virtual float GetStationaryY() const
Definition Object.h:810
void PlayDirectSound(uint32 sound_id, Player *target=NULL)
Definition Object.cpp:3442
TempSummon * SummonCreature(uint32 id, Position const &pos, TempSummonType spwtype=TempSummonType::TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0) const
Definition Object.cpp:2703
bool CanDetect(WorldObject const *obj, bool ignoreStealth) const
Definition Object.cpp:2195
std::set< uint32 > _phases
Definition Object.h:840
bool CanSeeOrDetect(WorldObject const *obj, bool ignoreStealth=false, bool distanceCheck=false) const
Definition Object.cpp:2105
virtual float GetStationaryZ() const
Definition Object.h:811
Map * m_currMap
Definition Object.h:835
virtual bool CanAlwaysSee(WorldObject const *) const
Definition Object.h:849
bool IsInMap(WorldObject const *obj) const
Definition Object.cpp:1703
virtual uint64 GetTransGUID() const
Definition Object.cpp:3571
Transport * m_transport
Definition Object.h:821
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:3105
virtual uint8 getLevelForTarget(WorldObject const *) const
Definition Object.h:702
void GetRandomPoint(Position const &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1950
virtual void UpdateObjectVisibility(bool forced=true)
Definition Object.cpp:3480
virtual void CleanupsBeforeDelete(bool finalCleanup=true)
Definition Object.cpp:1575
LocaleConstant GetSessionDbLocaleIndex() const
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void SendSetPhaseShift(std::set< uint32 > const &phaseIds, std::set< uint32 > const &terrainswaps, std::set< uint32 > const &worldAreas)
@ SMSG_GAMEOBJECT_DESPAWN_ANIM
Definition Opcodes.h:660
@ SMSG_DESTROY_OBJECT
Definition Opcodes.h:635
@ SMSG_PLAY_OBJECT_SOUND
Definition Opcodes.h:880
@ SMSG_PLAY_SOUND
Definition Opcodes.h:883
@ SMSG_ARENA_UNIT_DESTROYED
Definition Opcodes.h:518
#define sWorld
Definition World.h:910
@ CONFIG_LISTEN_RANGE_YELL
Definition World.h:185
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition World.h:184
@ CONFIG_LISTEN_RANGE_SAY
Definition World.h:183
std::string MovementFlags_ToString(uint32 flags)
std::string MovementFlagsExtra_ToString(uint32 flags)
bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
Definition Containers.h:56
void NormalizeMapCoord(float &c)
bool IsValidMapCoord(float c)
CellCoord ComputeCellCoord(float x, float y)
Definition Cell.h:37
void SetNoCreate()
Definition Cell.h:66
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition CellImpl.h:109
int32 rootPhaseMap
uint64 guid
Definition Object.h:449
uint32 time
Definition Object.h:453
struct MovementInfo::JumpInfo jump
uint16 flags2
Definition Object.h:451
uint32 flags
Definition Object.h:450
struct MovementInfo::TransportInfo transport
float splineElevation
Definition Object.h:494
float pitch
Definition Object.h:477
void OutDebug()
Definition Object.cpp:1479
Position pos
Definition Object.h:452
ConditionList Conditions
Definition ObjectMgr.h:702
float GetAngle(Position const *pos) const
Definition Object.cpp:1860
float m_positionZ
Definition Object.h:289
float GetExactDist2dSq(float x, float y) const
Definition Object.h:362
float GetExactDist2d(const float x, const float y) const
Definition Object.h:366
std::string ToString() const
Definition Object.cpp:1441
float GetExactDist(float x, float y, float z) const
Definition Object.h:382
static float NormalizeOrientation(float o)
Definition Object.h:427
float m_positionX
Definition Object.h:287
float GetPositionZ() const
Definition Object.h:330
float m_positionY
Definition Object.h:288
bool operator==(Position const &a)
Definition Object.cpp:1424
bool IsInDist2d(float x, float y, float dist) const
Definition Object.h:406
float GetOrientation() const
Definition Object.h:331
bool IsInDist(float x, float y, float z, float dist) const
Definition Object.h:414
bool HasInArc(float arcangle, Position const *pos, float border=2.0f) const
Definition Object.cpp:1898
bool IsPositionValid() const
Definition Object.cpp:2049
void GetSinCos(float x, float y, float &vsin, float &vcos) const
Definition Object.cpp:1879
void SetOrientation(float orientation)
Definition Object.h:323
float GetRelativeAngle(Position const *pos) const
Definition Object.h:399
bool HasInLine(WorldObject const *target, float width) const
Definition Object.cpp:1432
float m_orientation
Definition Object.h:292
float GetPositionX() const
Definition Object.h:328
void GetPosition(float &x, float &y) const
Definition Object.h:333
void GetPositionOffsetTo(Position const &endPos, Position &retOffset) const
Definition Object.cpp:1849
float GetPositionY() const
Definition Object.h:329
void RelocateOffset(Position const &offset)
Definition Object.cpp:1841
void Relocate(float x, float y)
Definition Object.h:302
uint32 Flags
uint32 Type
uint32 Category
uint32 m_ID
UpdateDataMapType & i_updateDatas
Definition Object.cpp:3489
WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d)
Definition Object.cpp:3492
void Visit(GridRefManager< SKIP > &)
Definition Object.cpp:3554
void Visit(PlayerMapType &m)
Definition Object.cpp:3493
void Visit(DynamicObjectMapType &m)
Definition Object.cpp:3526
void BuildPacket(Player *player)
Definition Object.cpp:3544
std::set< uint64 > plr_list
Definition Object.cpp:3491
void Visit(CreatureMapType &m)
Definition Object.cpp:3511
struct GameObjectValue::@210223111052332366220354331325332170103204164100 Transport
uint32 PathProgress
Definition GameObject.h:539
Position const MovePosition