2 * Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
3 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
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.
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
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/>.
23 #include "GridReference.h"
24 #include "GridRefManager.h"
25 #include "MovementInfo.h"
26 #include "ObjectDefines.h"
27 #include "ObjectGuid.h"
28 #include "PhaseShift.h"
30 #include "SharedDefines.h"
31 #include "UpdateFields.h"
33 #include <unordered_map>
53 struct QuaternionData
;
55 typedef std::unordered_map
<Player
*, UpdateData
> UpdateDataMapType
;
59 typedef uint32 BlockType
;
61 enum DynamicFieldChangeType
: uint16
64 VALUE_CHANGED
= 0x7FFF,
65 VALUE_AND_SIZE_CHANGED
= 0x8000
68 inline std::size_t GetBlockCount(std::size_t bitCount
)
70 using BitsPerBlock
= std::integral_constant
<std::size_t, sizeof(BlockType
) * 8>;
71 return (bitCount
+ BitsPerBlock::value
- 1) / BitsPerBlock::value
;
74 inline std::size_t EncodeDynamicFieldChangeType(std::size_t blockCount
, DynamicFieldChangeType changeType
, uint8 updateType
)
76 return blockCount
| ((changeType
& VALUE_AND_SIZE_CHANGED
) * ((3 - updateType
/*this part evaluates to 0 if update type is not VALUES*/) / 3));
80 inline void SetUpdateBit(T
* data
, std::size_t bitIndex
)
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
);
88 // Helper class used to iterate object dynamic fields while interpreting them as a structure instead of raw int array
90 class DynamicFieldStructuredView
93 explicit DynamicFieldStructuredView(std::vector
<uint32
> const& data
) : _data(data
) { }
95 T
const* begin() const
97 return reinterpret_cast<T
const*>(_data
.data());
102 return reinterpret_cast<T
const*>(_data
.data() + _data
.size());
105 std::size_t size() const
107 using BlockCount
= std::integral_constant
<uint16
, sizeof(T
) / sizeof(uint32
)>;
108 return _data
.size() / BlockCount::value
;
112 std::vector
<uint32
> const& _data
;
115 class TC_GAME_API Object
120 bool IsInWorld() const { return m_inWorld
; }
122 virtual void AddToWorld();
123 virtual void RemoveFromWorld();
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
); }
129 float GetObjectScale() const { return GetFloatValue(OBJECT_FIELD_SCALE_X
); }
130 virtual void SetObjectScale(float scale
) { SetFloatValue(OBJECT_FIELD_SCALE_X
, scale
); }
132 TypeID
GetTypeId() const { return m_objectTypeId
; }
133 bool isType(uint16 mask
) const { return (mask
& m_objectType
) != 0; }
135 virtual void BuildCreateUpdateBlockForPlayer(UpdateData
* data
, Player
* target
) const;
136 void SendUpdateToPlayer(Player
* player
);
138 void BuildValuesUpdateBlockForPlayer(UpdateData
* data
, Player
* target
) const;
139 void BuildOutOfRangeUpdateBlock(UpdateData
* data
) const;
141 virtual void DestroyForPlayer(Player
* target
) const;
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;
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
);
162 bool AddGuidValue(uint16 index
, ObjectGuid
const& value
);
163 bool RemoveGuidValue(uint16 index
, ObjectGuid
const& value
);
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
);
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
);
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;
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
);
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
);
197 DynamicFieldStructuredView
<T
> GetDynamicStructuredValues(uint16 index
) const
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
);
208 T
const* GetDynamicStructuredValue(uint16 index
, uint16 offset
) const
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())
217 return reinterpret_cast<T
const*>(&values
[offset
* BlockCount::value
]);
221 void SetDynamicStructuredValue(uint16 index
, uint16 offset
, T
const* value
)
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
));
231 void AddDynamicStructuredValue(uint16 index
, T
const* value
)
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
));
242 void ClearUpdateMask(bool remove
);
244 uint16
GetValuesCount() const { return m_valuesCount
; }
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;
251 void SetFieldNotifyFlag(uint16 flag
) { _fieldNotifyFlags
|= flag
; }
252 void RemoveFieldNotifyFlag(uint16 flag
) { _fieldNotifyFlags
&= uint16(~flag
); }
254 // FG: some hacky helpers
255 void ForceValuesUpdateAtIndex(uint32
);
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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
);
297 uint32
GetUpdateFieldData(Player
const* target
, uint32
*& flags
) const;
298 uint32
GetDynamicUpdateFieldData(Player
const* target
, uint32
*& flags
) const;
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;
306 TypeID m_objectTypeId
;
311 int32
*m_int32Values
;
312 uint32
*m_uint32Values
;
313 float *m_floatValues
;
316 std::vector
<uint32
>* _dynamicValues
;
318 std::vector
<uint8
> _changesMask
;
319 std::vector
<UpdateMask::DynamicFieldChangeType
> _dynamicChangesMask
;
320 std::vector
<uint8
>* _dynamicChangesArrayMask
;
322 uint16 m_valuesCount
;
323 uint16 _dynamicValuesCount
;
325 uint16 _fieldNotifyFlags
;
327 virtual void AddToObjectUpdate() = 0;
328 virtual void RemoveFromObjectUpdate() = 0;
329 void AddToObjectUpdateIfNeeded();
331 bool m_objectUpdated
;
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;
346 virtual ~GridObject() { }
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(); }
352 GridReference
<T
> _gridRef
;
355 template <class T_VALUES
, class T_FLAGS
, class FLAG_TYPE
, uint8 ARRAY_SIZE
>
356 class FlaggedValuesArray32
359 FlaggedValuesArray32()
361 for (uint32 i
= 0; i
< ARRAY_SIZE
; ++i
)
362 m_values
[i
] = T_VALUES(0);
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
); }
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
; }
376 T_VALUES m_values
[ARRAY_SIZE
];
380 class TC_GAME_API WorldObject
: public Object
, public WorldLocation
383 explicit WorldObject(bool isWorldObject
); //note: here it means if it is in grid object list or world object list
385 virtual ~WorldObject();
387 virtual void Update (uint32
/*time_diff*/) { }
389 virtual void RemoveFromWorld() override
;
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;
401 float GetObjectSize() const;
402 void UpdateGroundPositionZ(float x
, float y
, float &z
) const;
403 void UpdateAllowedPositionZ(float x
, float y
, float &z
) const;
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;
408 uint32
GetInstanceId() const { return m_InstanceId
; }
410 bool IsInPhase(WorldObject
const* obj
) const
412 return GetPhaseShift().CanSee(obj
->GetPhaseShift());
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
; }
421 // if negative it is used as PhaseGroupId
422 void SetDBPhase(int32 p
) { _dbPhase
= p
; }
424 uint32
GetZoneId() const;
425 uint32
GetAreaId() const;
426 void GetZoneAndAreaId(uint32
& zoneid
, uint32
& areaid
) const;
428 InstanceScript
* GetInstanceScript();
430 std::string
const& GetName() const { return m_name
; }
431 void SetName(std::string
const& newname
) { m_name
=newname
; }
433 virtual std::string
const& GetNameForLocaleIdx(LocaleConstant
/*locale_idx*/) const { return m_name
; }
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;
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;
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
); }
465 virtual void CleanupsBeforeDelete(bool finalCleanup
= true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
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;
471 virtual uint8
GetLevelForTarget(WorldObject
const* /*target*/) const { return 1; }
473 void PlayDistanceSound(uint32 soundId
, Player
* target
= nullptr);
474 void PlayDirectSound(uint32 soundId
, Player
* target
= nullptr);
475 void PlayDirectMusic(uint32 musicId
, Player
* target
= nullptr);
477 virtual void SaveRespawnTime() { }
478 void AddObjectToRemoveList();
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;
485 FlaggedValuesArray32
<int32
, uint32
, StealthType
, TOTAL_STEALTH_TYPES
> m_stealth
;
486 FlaggedValuesArray32
<int32
, uint32
, StealthType
, TOTAL_STEALTH_TYPES
> m_stealthDetect
;
488 FlaggedValuesArray32
<int32
, uint32
, InvisibilityType
, TOTAL_INVISIBILITY_TYPES
> m_invisibility
;
489 FlaggedValuesArray32
<int32
, uint32
, InvisibilityType
, TOTAL_INVISIBILITY_TYPES
> m_invisibilityDetect
;
491 FlaggedValuesArray32
<int32
, uint32
, ServerSideVisibilityType
, TOTAL_SERVERSIDE_VISIBILITY_TYPES
> m_serverSideVisibility
;
492 FlaggedValuesArray32
<int32
, uint32
, ServerSideVisibilityType
, TOTAL_SERVERSIDE_VISIBILITY_TYPES
> m_serverSideVisibilityDetect
;
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!
500 void SetZoneScript();
501 ZoneScript
* GetZoneScript() const { return m_zoneScript
; }
503 Scenario
* GetScenario() const;
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
);
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;
516 template <typename Container
>
517 void GetGameObjectListWithEntryInGrid(Container
& gameObjectContainer
, uint32 entry
, float maxSearchRange
= 250.0f
) const;
519 template <typename Container
>
520 void GetCreatureListWithEntryInGrid(Container
& creatureContainer
, uint32 entry
, float maxSearchRange
= 250.0f
) const;
522 template <typename Container
>
523 void GetPlayerListInGrid(Container
& playerContainer
, float maxSearchRange
) const;
525 void DestroyForNearbyPlayers();
526 virtual void UpdateObjectVisibility(bool forced
= true);
527 virtual void UpdateObjectVisibilityOnCreate()
529 UpdateObjectVisibility(true);
532 void BuildUpdate(UpdateDataMapType
&) override
;
533 void AddToObjectUpdate() override
;
534 void RemoveFromObjectUpdate() override
;
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; }
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;
550 uint32 LastUsedScriptID
;
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
; }
564 MovementInfo m_movementInfo
;
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(); }
571 virtual uint16
GetAIAnimKitId() const { return 0; }
572 virtual uint16
GetMovementAnimKitId() const { return 0; }
573 virtual uint16
GetMeleeAnimKitId() const { return 0; }
578 const bool m_isWorldObject
;
579 ZoneScript
* m_zoneScript
;
582 Transport
* m_transport
;
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
; }
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; }
596 Map
* m_currMap
; //current object's Map location
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
604 uint16 m_notifyflags
;
605 uint16 m_executed_notifies
;
606 virtual bool _IsWithinDist(WorldObject
const* obj
, float dist2compare
, bool is3D
) const;
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;
617 // Binary predicate to sort WorldObjects based on the distance to a reference WorldObject
618 class ObjectDistanceOrderPred
621 ObjectDistanceOrderPred(WorldObject
const* refObj
, bool ascending
= true) : _refObj(refObj
), _ascending(ascending
) { }
623 bool operator()(WorldObject
const* left
, WorldObject
const* right
) const
625 return _refObj
->GetDistanceOrder(left
, right
) == _ascending
;
629 WorldObject
const* _refObj
;