Core/Spells: Implemented personal summons (#19231)
[trinitycore] / src / server / game / Entities / Object / Object.h
1 /*
2 * Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
3 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifndef _OBJECT_H
20 #define _OBJECT_H
21
22 #include "Common.h"
23 #include "GridReference.h"
24 #include "GridRefManager.h"
25 #include "MovementInfo.h"
26 #include "ObjectDefines.h"
27 #include "ObjectGuid.h"
28 #include "PhaseShift.h"
29 #include "Position.h"
30 #include "SharedDefines.h"
31 #include "UpdateFields.h"
32 #include <list>
33 #include <unordered_map>
34
35 class AreaTrigger;
36 class Conversation;
37 class Corpse;
38 class Creature;
39 class CreatureAI;
40 class DynamicObject;
41 class GameObject;
42 class InstanceScript;
43 class Map;
44 class Player;
45 class Scenario;
46 class TempSummon;
47 class Transport;
48 class Unit;
49 class UpdateData;
50 class WorldObject;
51 class WorldPacket;
52 class ZoneScript;
53 struct QuaternionData;
54
55 typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
56
57 namespace UpdateMask
58 {
59 typedef uint32 BlockType;
60
61 enum DynamicFieldChangeType : uint16
62 {
63 UNCHANGED = 0,
64 VALUE_CHANGED = 0x7FFF,
65 VALUE_AND_SIZE_CHANGED = 0x8000
66 };
67
68 inline std::size_t GetBlockCount(std::size_t bitCount)
69 {
70 using BitsPerBlock = std::integral_constant<std::size_t, sizeof(BlockType) * 8>;
71 return (bitCount + BitsPerBlock::value - 1) / BitsPerBlock::value;
72 }
73
74 inline std::size_t EncodeDynamicFieldChangeType(std::size_t blockCount, DynamicFieldChangeType changeType, uint8 updateType)
75 {
76 return blockCount | ((changeType & VALUE_AND_SIZE_CHANGED) * ((3 - updateType /*this part evaluates to 0 if update type is not VALUES*/) / 3));
77 }
78
79 template<typename T>
80 inline void SetUpdateBit(T* data, std::size_t bitIndex)
81 {
82 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, "Type used for SetUpdateBit data arg is not an unsigned integer");
83 using BitsPerBlock = std::integral_constant<std::size_t, sizeof(T) * 8>;
84 data[bitIndex / BitsPerBlock::value] |= T(1) << (bitIndex % BitsPerBlock::value);
85 }
86 }
87
88 // Helper class used to iterate object dynamic fields while interpreting them as a structure instead of raw int array
89 template<class T>
90 class DynamicFieldStructuredView
91 {
92 public:
93 explicit DynamicFieldStructuredView(std::vector<uint32> const& data) : _data(data) { }
94
95 T const* begin() const
96 {
97 return reinterpret_cast<T const*>(_data.data());
98 }
99
100 T const* end() const
101 {
102 return reinterpret_cast<T const*>(_data.data() + _data.size());
103 }
104
105 std::size_t size() const
106 {
107 using BlockCount = std::integral_constant<uint16, sizeof(T) / sizeof(uint32)>;
108 return _data.size() / BlockCount::value;
109 }
110
111 private:
112 std::vector<uint32> const& _data;
113 };
114
115 class TC_GAME_API Object
116 {
117 public:
118 virtual ~Object();
119
120 bool IsInWorld() const { return m_inWorld; }
121
122 virtual void AddToWorld();
123 virtual void RemoveFromWorld();
124
125 ObjectGuid const& GetGUID() const { return GetGuidValue(OBJECT_FIELD_GUID); }
126 uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
127 void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
128
129 float GetObjectScale() const { return GetFloatValue(OBJECT_FIELD_SCALE_X); }
130 virtual void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
131
132 TypeID GetTypeId() const { return m_objectTypeId; }
133 bool isType(uint16 mask) const { return (mask & m_objectType) != 0; }
134
135 virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const;
136 void SendUpdateToPlayer(Player* player);
137
138 void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const;
139 void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
140
141 virtual void DestroyForPlayer(Player* target) const;
142
143 int32 GetInt32Value(uint16 index) const;
144 uint32 GetUInt32Value(uint16 index) const;
145 uint64 GetUInt64Value(uint16 index) const;
146 float GetFloatValue(uint16 index) const;
147 uint8 GetByteValue(uint16 index, uint8 offset) const;
148 uint16 GetUInt16Value(uint16 index, uint8 offset) const;
149 ObjectGuid const& GetGuidValue(uint16 index) const;
150
151 void SetInt32Value(uint16 index, int32 value);
152 void SetUInt32Value(uint16 index, uint32 value);
153 void UpdateUInt32Value(uint16 index, uint32 value);
154 void SetUInt64Value(uint16 index, uint64 value);
155 void SetFloatValue(uint16 index, float value);
156 void SetByteValue(uint16 index, uint8 offset, uint8 value);
157 void SetUInt16Value(uint16 index, uint8 offset, uint16 value);
158 void SetGuidValue(uint16 index, ObjectGuid const& value);
159 void SetStatFloatValue(uint16 index, float value);
160 void SetStatInt32Value(uint16 index, int32 value);
161
162 bool AddGuidValue(uint16 index, ObjectGuid const& value);
163 bool RemoveGuidValue(uint16 index, ObjectGuid const& value);
164
165 void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
166 void ApplyModInt32Value(uint16 index, int32 val, bool apply);
167 void ApplyModUInt16Value(uint16 index, uint8 offset, int16 val, bool apply);
168 void ApplyModPositiveFloatValue(uint16 index, float val, bool apply);
169 void ApplyModSignedFloatValue(uint16 index, float val, bool apply);
170 void ApplyPercentModFloatValue(uint16 index, float val, bool apply);
171
172 void SetFlag(uint16 index, uint32 newFlag);
173 void RemoveFlag(uint16 index, uint32 oldFlag);
174 void ToggleFlag(uint16 index, uint32 flag);
175 bool HasFlag(uint16 index, uint32 flag) const;
176 void ApplyModFlag(uint16 index, uint32 flag, bool apply);
177
178 void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag);
179 void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag);
180 void ToggleByteFlag(uint16 index, uint8 offset, uint8 flag);
181 bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const;
182
183 void SetFlag64(uint16 index, uint64 newFlag);
184 void RemoveFlag64(uint16 index, uint64 oldFlag);
185 void ToggleFlag64(uint16 index, uint64 flag);
186 bool HasFlag64(uint16 index, uint64 flag) const;
187 void ApplyModFlag64(uint16 index, uint64 flag, bool apply);
188
189 std::vector<uint32> const& GetDynamicValues(uint16 index) const;
190 uint32 GetDynamicValue(uint16 index, uint16 offset) const;
191 void AddDynamicValue(uint16 index, uint32 value);
192 void RemoveDynamicValue(uint16 index, uint32 value);
193 void ClearDynamicValue(uint16 index);
194 void SetDynamicValue(uint16 index, uint16 offset, uint32 value);
195
196 template<class T>
197 DynamicFieldStructuredView<T> GetDynamicStructuredValues(uint16 index) const
198 {
199 static_assert(std::is_standard_layout<T>::value && std::is_trivially_destructible<T>::value, "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type");
200 using BlockCount = std::integral_constant<uint16, sizeof(T) / sizeof(uint32)>;
201 ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false));
202 std::vector<uint32> const& values = _dynamicValues[index];
203 ASSERT((values.size() % BlockCount::value) == 0, "Dynamic field value count must exactly fit into structure");
204 return DynamicFieldStructuredView<T>(values);
205 }
206
207 template<class T>
208 T const* GetDynamicStructuredValue(uint16 index, uint16 offset) const
209 {
210 static_assert(std::is_standard_layout<T>::value && std::is_trivially_destructible<T>::value, "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type");
211 using BlockCount = std::integral_constant<uint16, sizeof(T) / sizeof(uint32)>;
212 ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false));
213 std::vector<uint32> const& values = _dynamicValues[index];
214 ASSERT((values.size() % BlockCount::value) == 0, "Dynamic field value count must exactly fit into structure");
215 if (offset * BlockCount::value >= values.size())
216 return nullptr;
217 return reinterpret_cast<T const*>(&values[offset * BlockCount::value]);
218 }
219
220 template<class T>
221 void SetDynamicStructuredValue(uint16 index, uint16 offset, T const* value)
222 {
223 static_assert(std::is_standard_layout<T>::value && std::is_trivially_destructible<T>::value, "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type");
224 using BlockCount = std::integral_constant<uint16, sizeof(T) / sizeof(uint32)>;
225 SetDynamicValue(index, (offset + 1) * BlockCount::value - 1, 0); // reserve space
226 for (uint16 i = 0; i < BlockCount::value; ++i)
227 SetDynamicValue(index, offset * BlockCount::value + i, *(reinterpret_cast<uint32 const*>(value) + i));
228 }
229
230 template<class T>
231 void AddDynamicStructuredValue(uint16 index, T const* value)
232 {
233 static_assert(std::is_standard_layout<T>::value && std::is_trivially_destructible<T>::value, "T used for Object::SetDynamicStructuredValue<T> is not a trivially destructible standard layout type");
234 using BlockCount = std::integral_constant<uint16, sizeof(T) / sizeof(uint32)>;
235 std::vector<uint32> const& values = _dynamicValues[index];
236 uint16 offset = uint16(values.size() / BlockCount::value);
237 SetDynamicValue(index, (offset + 1) * BlockCount::value - 1, 0); // reserve space
238 for (uint16 i = 0; i < BlockCount::value; ++i)
239 SetDynamicValue(index, offset * BlockCount::value + i, *(reinterpret_cast<uint32 const*>(value) + i));
240 }
241
242 void ClearUpdateMask(bool remove);
243
244 uint16 GetValuesCount() const { return m_valuesCount; }
245
246 virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
247 virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
248 virtual void BuildUpdate(UpdateDataMapType&) { }
249 void BuildFieldsUpdate(Player*, UpdateDataMapType &) const;
250
251 void SetFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags |= flag; }
252 void RemoveFieldNotifyFlag(uint16 flag) { _fieldNotifyFlags &= uint16(~flag); }
253
254 // FG: some hacky helpers
255 void ForceValuesUpdateAtIndex(uint32);
256
257 inline bool IsPlayer() const { return GetTypeId() == TYPEID_PLAYER; }
258 Player* ToPlayer() { if (IsPlayer()) return reinterpret_cast<Player*>(this); else return nullptr; }
259 Player const* ToPlayer() const { if (IsPlayer()) return reinterpret_cast<Player const*>(this); else return nullptr; }
260
261 inline bool IsCreature() const { return GetTypeId() == TYPEID_UNIT; }
262 Creature* ToCreature() { if (IsCreature()) return reinterpret_cast<Creature*>(this); else return nullptr; }
263 Creature const* ToCreature() const { if (IsCreature()) return reinterpret_cast<Creature const*>(this); else return nullptr; }
264
265 inline bool IsUnit() const { return isType(TYPEMASK_UNIT); }
266 Unit* ToUnit() { if (IsUnit()) return reinterpret_cast<Unit*>(this); else return nullptr; }
267 Unit const* ToUnit() const { if (IsUnit()) return reinterpret_cast<Unit const*>(this); else return nullptr; }
268
269 inline bool IsGameObject() const { return GetTypeId() == TYPEID_GAMEOBJECT; }
270 GameObject* ToGameObject() { if (IsGameObject()) return reinterpret_cast<GameObject*>(this); else return nullptr; }
271 GameObject const* ToGameObject() const { if (IsGameObject()) return reinterpret_cast<GameObject const*>(this); else return nullptr; }
272
273 inline bool IsCorpse() const { return GetTypeId() == TYPEID_CORPSE; }
274 Corpse* ToCorpse() { if (IsCorpse()) return reinterpret_cast<Corpse*>(this); else return nullptr; }
275 Corpse const* ToCorpse() const { if (IsCorpse()) return reinterpret_cast<Corpse const*>(this); else return nullptr; }
276
277 inline bool IsDynObject() const { return GetTypeId() == TYPEID_DYNAMICOBJECT; }
278 DynamicObject* ToDynObject() { if (IsDynObject()) return reinterpret_cast<DynamicObject*>(this); else return nullptr; }
279 DynamicObject const* ToDynObject() const { if (IsDynObject()) return reinterpret_cast<DynamicObject const*>(this); else return nullptr; }
280
281 inline bool IsAreaTrigger() const { return GetTypeId() == TYPEID_AREATRIGGER; }
282 AreaTrigger* ToAreaTrigger() { if (IsAreaTrigger()) return reinterpret_cast<AreaTrigger*>(this); else return nullptr; }
283 AreaTrigger const* ToAreaTrigger() const { if (IsAreaTrigger()) return reinterpret_cast<AreaTrigger const*>(this); else return nullptr; }
284
285 inline bool IsConversation() const { return GetTypeId() == TYPEID_CONVERSATION; }
286 Conversation* ToConversation() { if (GetTypeId() == TYPEID_CONVERSATION) return reinterpret_cast<Conversation*>(this); else return nullptr; }
287 Conversation const* ToConversation() const { if (GetTypeId() == TYPEID_CONVERSATION) return reinterpret_cast<Conversation const*>(this); else return nullptr; }
288
289 protected:
290 Object();
291
292 void _InitValues();
293 void _Create(ObjectGuid const& guid);
294 std::string _ConcatFields(uint16 startIndex, uint16 size) const;
295 void _LoadIntoDataField(std::string const& data, uint32 startOffset, uint32 count);
296
297 uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const;
298 uint32 GetDynamicUpdateFieldData(Player const* target, uint32*& flags) const;
299
300 void BuildMovementUpdate(ByteBuffer* data, uint32 flags) const;
301 virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
302 virtual void BuildDynamicValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
303
304 uint16 m_objectType;
305
306 TypeID m_objectTypeId;
307 uint32 m_updateFlag;
308
309 union
310 {
311 int32 *m_int32Values;
312 uint32 *m_uint32Values;
313 float *m_floatValues;
314 };
315
316 std::vector<uint32>* _dynamicValues;
317
318 std::vector<uint8> _changesMask;
319 std::vector<UpdateMask::DynamicFieldChangeType> _dynamicChangesMask;
320 std::vector<uint8>* _dynamicChangesArrayMask;
321
322 uint16 m_valuesCount;
323 uint16 _dynamicValuesCount;
324
325 uint16 _fieldNotifyFlags;
326
327 virtual void AddToObjectUpdate() = 0;
328 virtual void RemoveFromObjectUpdate() = 0;
329 void AddToObjectUpdateIfNeeded();
330
331 bool m_objectUpdated;
332
333 private:
334 bool m_inWorld;
335
336 // for output helpfull error messages from asserts
337 bool PrintIndexError(uint32 index, bool set) const;
338 Object(Object const& right) = delete;
339 Object& operator=(Object const& right) = delete;
340 };
341
342 template<class T>
343 class GridObject
344 {
345 public:
346 virtual ~GridObject() { }
347
348 bool IsInGrid() const { return _gridRef.isValid(); }
349 void AddToGrid(GridRefManager<T>& m) { ASSERT(!IsInGrid()); _gridRef.link(&m, (T*)this); }
350 void RemoveFromGrid() { ASSERT(IsInGrid()); _gridRef.unlink(); }
351 private:
352 GridReference<T> _gridRef;
353 };
354
355 template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, uint8 ARRAY_SIZE>
356 class FlaggedValuesArray32
357 {
358 public:
359 FlaggedValuesArray32()
360 {
361 for (uint32 i = 0; i < ARRAY_SIZE; ++i)
362 m_values[i] = T_VALUES(0);
363 m_flags = 0;
364 }
365
366 T_FLAGS GetFlags() const { return m_flags; }
367 bool HasFlag(FLAG_TYPE flag) const { return m_flags & (1 << flag); }
368 void AddFlag(FLAG_TYPE flag) { m_flags |= (1 << flag); }
369 void DelFlag(FLAG_TYPE flag) { m_flags &= ~(1 << flag); }
370
371 T_VALUES GetValue(FLAG_TYPE flag) const { return m_values[flag]; }
372 void SetValue(FLAG_TYPE flag, T_VALUES value) { m_values[flag] = value; }
373 void AddValue(FLAG_TYPE flag, T_VALUES value) { m_values[flag] += value; }
374
375 private:
376 T_VALUES m_values[ARRAY_SIZE];
377 T_FLAGS m_flags;
378 };
379
380 class TC_GAME_API WorldObject : public Object, public WorldLocation
381 {
382 protected:
383 explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list
384 public:
385 virtual ~WorldObject();
386
387 virtual void Update (uint32 /*time_diff*/) { }
388
389 virtual void RemoveFromWorld() override;
390
391 void GetNearPoint2D(float &x, float &y, float distance, float absAngle) const;
392 void GetNearPoint(WorldObject const* searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle) const;
393 void GetClosePoint(float &x, float &y, float &z, float size, float distance2d = 0, float angle = 0) const;
394 void MovePosition(Position &pos, float dist, float angle);
395 Position GetNearPosition(float dist, float angle);
396 void MovePositionToFirstCollision(Position &pos, float dist, float angle);
397 Position GetFirstCollisionPosition(float dist, float angle);
398 Position GetRandomNearPosition(float radius);
399 void GetContactPoint(WorldObject const* obj, float &x, float &y, float &z, float distance2d = CONTACT_DISTANCE) const;
400
401 float GetObjectSize() const;
402 void UpdateGroundPositionZ(float x, float y, float &z) const;
403 void UpdateAllowedPositionZ(float x, float y, float &z) const;
404
405 void GetRandomPoint(Position const &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const;
406 Position GetRandomPoint(Position const &srcPos, float distance) const;
407
408 uint32 GetInstanceId() const { return m_InstanceId; }
409
410 bool IsInPhase(WorldObject const* obj) const
411 {
412 return GetPhaseShift().CanSee(obj->GetPhaseShift());
413 }
414
415 PhaseShift& GetPhaseShift() { return _phaseShift; }
416 PhaseShift const& GetPhaseShift() const { return _phaseShift; }
417 PhaseShift& GetSuppressedPhaseShift() { return _suppressedPhaseShift; }
418 PhaseShift const& GetSuppressedPhaseShift() const { return _suppressedPhaseShift; }
419 int32 GetDBPhase() const { return _dbPhase; }
420
421 // if negative it is used as PhaseGroupId
422 void SetDBPhase(int32 p) { _dbPhase = p; }
423
424 uint32 GetZoneId() const;
425 uint32 GetAreaId() const;
426 void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const;
427
428 InstanceScript* GetInstanceScript();
429
430 std::string const& GetName() const { return m_name; }
431 void SetName(std::string const& newname) { m_name=newname; }
432
433 virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale_idx*/) const { return m_name; }
434
435 float GetDistance(WorldObject const* obj) const;
436 float GetDistance(Position const &pos) const;
437 float GetDistance(float x, float y, float z) const;
438 float GetDistance2d(WorldObject const* obj) const;
439 float GetDistance2d(float x, float y) const;
440 float GetDistanceZ(WorldObject const* obj) const;
441
442 bool IsSelfOrInSameMap(WorldObject const* obj) const;
443 bool IsInMap(WorldObject const* obj) const;
444 bool IsWithinDist3d(float x, float y, float z, float dist) const;
445 bool IsWithinDist3d(Position const* pos, float dist) const;
446 bool IsWithinDist2d(float x, float y, float dist) const;
447 bool IsWithinDist2d(Position const* pos, float dist) const;
448 // use only if you will sure about placing both object at same map
449 bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const;
450 bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const;
451 bool IsWithinLOS(float x, float y, float z) const;
452 bool IsWithinLOSInMap(WorldObject const* obj) const;
453 Position GetHitSpherePointFor(Position const& dest) const;
454 void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const;
455 bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const;
456 bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const;
457 bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
458 bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const;
459 bool isInFront(WorldObject const* target, float arc = float(M_PI)) const;
460 bool isInBack(WorldObject const* target, float arc = float(M_PI)) const;
461
462 bool IsInBetween(Position const& pos1, Position const& pos2, float size = 0) const;
463 bool IsInBetween(WorldObject const* obj1, WorldObject const* obj2, float size = 0) const { return obj1 && obj2 && IsInBetween(obj1->GetPosition(), obj2->GetPosition(), size); }
464
465 virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
466
467 virtual void SendMessageToSet(WorldPacket const* data, bool self) const;
468 virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const;
469 virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const;
470
471 virtual uint8 GetLevelForTarget(WorldObject const* /*target*/) const { return 1; }
472
473 void PlayDistanceSound(uint32 soundId, Player* target = nullptr);
474 void PlayDirectSound(uint32 soundId, Player* target = nullptr);
475 void PlayDirectMusic(uint32 musicId, Player* target = nullptr);
476
477 virtual void SaveRespawnTime() { }
478 void AddObjectToRemoveList();
479
480 float GetGridActivationRange() const;
481 float GetVisibilityRange() const;
482 float GetSightRange(WorldObject const* target = NULL) const;
483 bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false) const;
484
485 FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealth;
486 FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealthDetect;
487
488 FlaggedValuesArray32<int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES> m_invisibility;
489 FlaggedValuesArray32<int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES> m_invisibilityDetect;
490
491 FlaggedValuesArray32<int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES> m_serverSideVisibility;
492 FlaggedValuesArray32<int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES> m_serverSideVisibilityDetect;
493
494 virtual void SetMap(Map* map);
495 virtual void ResetMap();
496 Map* GetMap() const { ASSERT(m_currMap); return m_currMap; }
497 Map* FindMap() const { return m_currMap; }
498 //used to check all object's GetMap() calls when object is not in world!
499
500 void SetZoneScript();
501 ZoneScript* GetZoneScript() const { return m_zoneScript; }
502
503 Scenario* GetScenario() const;
504
505 TempSummon* SummonCreature(uint32 id, Position const& pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0, bool visibleBySummonerOnly = false);
506 TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, bool visibleBySummonerOnly = false);
507 GameObject* SummonGameObject(uint32 entry, Position const& pos, QuaternionData const& rot, uint32 respawnTime /* s */);
508 GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, QuaternionData const& rot, uint32 respawnTime /* s */);
509 Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL);
510 void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL);
511
512 Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const;
513 GameObject* FindNearestGameObject(uint32 entry, float range) const;
514 GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const;
515
516 template <typename Container>
517 void GetGameObjectListWithEntryInGrid(Container& gameObjectContainer, uint32 entry, float maxSearchRange = 250.0f) const;
518
519 template <typename Container>
520 void GetCreatureListWithEntryInGrid(Container& creatureContainer, uint32 entry, float maxSearchRange = 250.0f) const;
521
522 template <typename Container>
523 void GetPlayerListInGrid(Container& playerContainer, float maxSearchRange) const;
524
525 void DestroyForNearbyPlayers();
526 virtual void UpdateObjectVisibility(bool forced = true);
527 virtual void UpdateObjectVisibilityOnCreate()
528 {
529 UpdateObjectVisibility(true);
530 }
531
532 void BuildUpdate(UpdateDataMapType&) override;
533 void AddToObjectUpdate() override;
534 void RemoveFromObjectUpdate() override;
535
536 //relocation and visibility system functions
537 void AddToNotify(uint16 f) { m_notifyflags |= f;}
538 bool isNeedNotify(uint16 f) const { return (m_notifyflags & f) != 0; }
539 uint16 GetNotifyFlags() const { return m_notifyflags; }
540 bool NotifyExecuted(uint16 f) const { return (m_executed_notifies & f) != 0; }
541 void SetNotified(uint16 f) { m_executed_notifies |= f;}
542 void ResetAllNotifies() { m_notifyflags = 0; m_executed_notifies = 0; }
543
544 bool isActiveObject() const { return m_isActive; }
545 void setActive(bool isActiveObject);
546 void SetWorldObject(bool apply);
547 bool IsPermanentWorldObject() const { return m_isWorldObject; }
548 bool IsWorldObject() const;
549
550 uint32 LastUsedScriptID;
551
552 // Transports
553 Transport* GetTransport() const { return m_transport; }
554 float GetTransOffsetX() const { return m_movementInfo.transport.pos.GetPositionX(); }
555 float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); }
556 float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); }
557 float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); }
558 Position const& GetTransOffset() const { return m_movementInfo.transport.pos; }
559 uint32 GetTransTime() const { return m_movementInfo.transport.time; }
560 int8 GetTransSeat() const { return m_movementInfo.transport.seat; }
561 virtual ObjectGuid GetTransGUID() const;
562 void SetTransport(Transport* t) { m_transport = t; }
563
564 MovementInfo m_movementInfo;
565
566 virtual float GetStationaryX() const { return GetPositionX(); }
567 virtual float GetStationaryY() const { return GetPositionY(); }
568 virtual float GetStationaryZ() const { return GetPositionZ(); }
569 virtual float GetStationaryO() const { return GetOrientation(); }
570
571 virtual uint16 GetAIAnimKitId() const { return 0; }
572 virtual uint16 GetMovementAnimKitId() const { return 0; }
573 virtual uint16 GetMeleeAnimKitId() const { return 0; }
574
575 protected:
576 std::string m_name;
577 bool m_isActive;
578 const bool m_isWorldObject;
579 ZoneScript* m_zoneScript;
580
581 // transports
582 Transport* m_transport;
583
584 //these functions are used mostly for Relocate() and Corpse/Player specific stuff...
585 //use them ONLY in LoadFromDB()/Create() funcs and nowhere else!
586 //mapId/instanceId should be set in SetMap() function!
587 void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
588 void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }
589
590 virtual bool IsNeverVisibleFor(WorldObject const* /*seer*/) const { return !IsInWorld(); }
591 virtual bool IsAlwaysVisibleFor(WorldObject const* /*seer*/) const { return false; }
592 virtual bool IsInvisibleDueToDespawn() const { return false; }
593 //difference from IsAlwaysVisibleFor: 1. after distance check; 2. use owner or charmer as seer
594 virtual bool IsAlwaysDetectableFor(WorldObject const* /*seer*/) const { return false; }
595 private:
596 Map* m_currMap; //current object's Map location
597
598 //uint32 m_mapId; // object at map with map_id
599 uint32 m_InstanceId; // in map copy with instance id
600 PhaseShift _phaseShift;
601 PhaseShift _suppressedPhaseShift; // contains phases for current area but not applied due to conditions
602 int32 _dbPhase;
603
604 uint16 m_notifyflags;
605 uint16 m_executed_notifies;
606 virtual bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const;
607
608 bool CanNeverSee(WorldObject const* obj) const;
609 virtual bool CanAlwaysSee(WorldObject const* /*obj*/) const { return false; }
610 bool CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert = false) const;
611 bool CanDetectInvisibilityOf(WorldObject const* obj) const;
612 bool CanDetectStealthOf(WorldObject const* obj, bool checkAlert = false) const;
613 };
614
615 namespace Trinity
616 {
617 // Binary predicate to sort WorldObjects based on the distance to a reference WorldObject
618 class ObjectDistanceOrderPred
619 {
620 public:
621 ObjectDistanceOrderPred(WorldObject const* refObj, bool ascending = true) : _refObj(refObj), _ascending(ascending) { }
622
623 bool operator()(WorldObject const* left, WorldObject const* right) const
624 {
625 return _refObj->GetDistanceOrder(left, right) == _ascending;
626 }
627
628 private:
629 WorldObject const* _refObj;
630 bool _ascending;
631 };
632 }
633
634 #endif