TrinityCore
Loading...
Searching...
No Matches
BaseEntity.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITYCORE_BASE_ENTITY_H
19#define TRINITYCORE_BASE_ENTITY_H
20
21#include "Common.h"
22#include "ObjectGuid.h"
23#include "UpdateFields.h"
25#include <unordered_map>
26
27class BaseEntity;
28class Player;
29class UpdateData;
30class WorldPacket;
31
32typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
33
35{
37 bool NoBirthAnim : 1;
38 bool EnablePortals : 1;
39 bool PlayHoverAnim : 1;
40 bool ThisIsYou : 1;
43 bool Stationary : 1;
44 bool CombatVictim : 1;
45 bool ServerTime : 1;
46 bool Vehicle : 1;
47 bool AnimKit : 1;
48 bool Rotation : 1;
49 bool GameObject : 1;
50 bool SmoothPhasing : 1;
51 bool SceneObject : 1;
52 bool ActivePlayer : 1;
53 bool Conversation : 1;
54 bool Room : 1;
55 bool Decor : 1;
56 bool MeshObject : 1;
57
58 void Clear()
59 {
60 memset(this, 0, sizeof(CreateObjectBits));
61 }
62};
63
64namespace UF
65{
67 {
68 public:
69 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
71
72 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
74
75 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
77
78 template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
79 inline void ClearChangesMask(UpdateField<T, BlockBit, Bit>(Derived::* field));
80
82
83 bool HasChanged(uint32 index) const { return (_changesMask & UpdateMaskHelpers::GetBlockFlag(index)) != 0; }
84
85 inline BaseEntity* GetOwner();
86
87 private:
88 friend BaseEntity;
89
90 // This class is tightly tied to BaseEntity::m_values member, do not construct elsewhere
91 UpdateFieldHolder() = default;
92
93 uint32 _changesMask = 0; // changes mask for data of Object subclasses
94 };
95
96 template<typename T>
98 {
99 return setter.SetValue(std::move(value));
100 }
101
102 template<typename T>
107
108 template<typename T>
113
114 template<typename T>
116 {
117 setter.RemoveValue(index);
118 }
119
120 template<typename T>
122 {
123 setter.Clear();
124 }
125
126 template<typename K, typename V>
127 inline bool RemoveMapUpdateFieldValue(MapUpdateFieldSetter<K, V>& setter, std::type_identity_t<K> const& key)
128 {
129 return setter.RemoveKey(key);
130 }
131
132 template<typename T>
133 inline bool InsertSetUpdateFieldValue(SetUpdateFieldSetter<T>& setter, std::type_identity_t<T> const& key)
134 {
135 return setter.Insert(key);
136 }
137
138 template<typename T>
139 inline bool RemoveSetUpdateFieldValue(SetUpdateFieldSetter<T>& setter, std::type_identity_t<T> const& key)
140 {
141 return setter.Remove(key);
142 }
143
144 template<typename T>
146 {
147 return setter.RemoveValue();
148 }
149}
150
152{
154
155 public:
156 virtual ~BaseEntity();
157
158 bool IsInWorld() const { return m_inWorld; }
159
160 virtual void AddToWorld();
161 virtual void RemoveFromWorld();
162
163 ObjectGuid const& GetGUID() const { return m_guid; }
164 static ObjectGuid GetGUID(BaseEntity const* o) { return o ? o->GetGUID() : ObjectGuid::Empty; }
165
166 TypeID GetTypeId() const { return m_objectTypeId; }
167 bool isType(TypeMask mask) const { return (ObjectTypeMask[m_objectTypeId] & mask) != 0; }
168
169 inline bool IsWorldObject() const { return isType(TYPEMASK_WORLDOBJECT); }
170 inline bool IsItem() const { return isType(TYPEMASK_ITEM); }
171 inline bool IsUnit() const { return isType(TYPEMASK_UNIT); }
172 inline bool IsCreature() const { return GetTypeId() == TYPEID_UNIT; }
173 inline bool IsPlayer() const { return GetTypeId() == TYPEID_PLAYER; }
174 inline bool IsGameObject() const { return GetTypeId() == TYPEID_GAMEOBJECT; }
175 inline bool IsDynObject() const { return GetTypeId() == TYPEID_DYNAMICOBJECT; }
176 inline bool IsCorpse() const { return GetTypeId() == TYPEID_CORPSE; }
177 inline bool IsAreaTrigger() const { return GetTypeId() == TYPEID_AREATRIGGER; }
178 inline bool IsSceneObject() const { return GetTypeId() == TYPEID_SCENEOBJECT; }
179 inline bool IsConversation() const { return GetTypeId() == TYPEID_CONVERSATION; }
180 inline bool IsMeshObject() const { return GetTypeId() == TYPEID_MESH_OBJECT; }
181
182 virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const;
183 void SendUpdateToPlayer(Player* player) const;
184
185 void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const* target) const;
186 void BuildDestroyUpdateBlock(UpdateData* data) const;
187 void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
188 ByteBuffer& PrepareValuesUpdateBuffer(UpdateData* data) const;
189
190 virtual void DestroyForPlayer(Player const* target) const;
191 void SendOutOfRangeForPlayer(Player const* target) const;
192
193 void ClearUpdateMask(bool remove);
194
195 virtual std::string GetNameForLocaleIdx(LocaleConstant locale) const = 0;
196
197 void SetIsNewObject(bool enable) { m_isNewObject = enable; }
198 bool IsDestroyedObject() const { return m_isDestroyedObject; }
199 void SetDestroyedObject(bool destroyed) { m_isDestroyedObject = destroyed; }
200 virtual void BuildUpdate([[maybe_unused]] UpdateDataMapType& data_map) { }
201 void BuildUpdateChangesMask();
202 void BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) const;
203
206
207 template<typename T>
209 {
210 AddToObjectUpdateIfNeeded();
211 }
212
213 virtual std::string GetDebugInfo() const;
214
215 protected:
217
218 void _Create(ObjectGuid const& guid) { m_guid = guid; }
219
220 template<typename T>
222 {
223 if (UF::SetUpdateFieldValue(setter, std::move(value)))
224 AddToObjectUpdateIfNeeded();
225 }
226
227 template<typename T>
229 {
230 static_assert(std::is_integral_v<T>, "SetUpdateFieldFlagValue must be used with integral types");
231 this->SetUpdateFieldValue(setter, setter.GetValue() | flag);
232 }
233
234 template<typename T>
236 {
237 static_assert(std::is_integral_v<T>, "RemoveUpdateFieldFlagValue must be used with integral types");
238 this->SetUpdateFieldValue(setter, setter.GetValue() & ~flag);
239 }
240
241 template<typename T>
247
248 template<typename T>
250 {
251 AddToObjectUpdateIfNeeded();
252 return UF::InsertDynamicUpdateFieldValue(setter, index);
253 }
254
255 template<typename T>
257 {
258 AddToObjectUpdateIfNeeded();
260 }
261
262 template<typename T>
264 {
265 AddToObjectUpdateIfNeeded();
267 }
268
269 template<typename K, typename V>
270 void RemoveMapUpdateFieldValue(UF::MapUpdateFieldSetter<K, V> setter, std::type_identity_t<K> const& key)
271 {
272 if (UF::RemoveMapUpdateFieldValue(setter, key))
273 AddToObjectUpdateIfNeeded();
274 }
275
276 template<typename T>
277 void InsertSetUpdateFieldValue(UF::SetUpdateFieldSetter<T> setter, std::type_identity_t<T> const& key)
278 {
279 if (UF::InsertSetUpdateFieldValue(setter, key))
280 AddToObjectUpdateIfNeeded();
281 }
282
283 template<typename T>
284 void RemoveSetUpdateFieldValue(UF::SetUpdateFieldSetter<T> setter, std::type_identity_t<T> const& key)
285 {
286 if (UF::RemoveSetUpdateFieldValue(setter, key))
287 AddToObjectUpdateIfNeeded();
288 }
289
290 template<typename T>
292 {
294 AddToObjectUpdateIfNeeded();
295 }
296
297 // stat system helpers
298 template<typename T>
300 {
301 static_assert(std::is_arithmetic_v<T>, "SetUpdateFieldStatValue must be used with arithmetic types");
302 this->SetUpdateFieldValue(setter, std::max(value, T(0)));
303 }
304
305 template<typename T>
307 {
308 static_assert(std::is_arithmetic_v<T>, "SetUpdateFieldStatValue must be used with arithmetic types");
309
310 T value = setter.GetValue();
311 if (apply)
312 value += mod;
313 else
314 value -= mod;
315
316 this->SetUpdateFieldValue(setter, value);
317 }
318
319 template<typename T>
321 {
322 static_assert(std::is_arithmetic_v<T>, "SetUpdateFieldStatValue must be used with arithmetic types");
323
324 T value = setter.GetValue();
325
326 // don't want to include Util.h here
327 //ApplyPercentModFloatVar(value, percent, apply);
328 if (percent == -100.0f)
329 percent = -99.99f;
330 value *= (apply ? (100.0f + percent) / 100.0f : 100.0f / (100.0f + percent));
331
332 this->SetUpdateFieldValue(setter, value);
333 }
334
335 template<typename Action>
337 {
338 bool wasUpdatedBeforeAction = m_objectUpdated;
339 action();
340 if (m_objectUpdated && !wasUpdatedBeforeAction)
341 {
342 RemoveFromObjectUpdate();
343 m_objectUpdated = false;
344 }
345 }
346
347 void BuildMovementUpdate(ByteBuffer& data, CreateObjectBits flags, Player const* target) const;
348 virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const;
349 static void BuildEntityFragments(ByteBuffer& data, std::span<WowCS::EntityFragment const> fragments);
350
352 CreateObjectBits m_updateFlag = {};
354
355 virtual bool AddToObjectUpdate() = 0;
356 virtual void RemoveFromObjectUpdate() = 0;
357 void AddToObjectUpdateIfNeeded();
358
359 bool m_objectUpdated = false;
360
361 private:
362 bool m_inWorld = false;
363 bool m_isNewObject = false;
364 bool m_isDestroyedObject = false;
365
366 BaseEntity(BaseEntity const& right) = delete;
367 BaseEntity(BaseEntity&& right) = delete;
368 BaseEntity& operator=(BaseEntity const& right) = delete;
369 BaseEntity& operator=(BaseEntity&& right) = delete;
370};
371
373{
374#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
375#pragma GCC diagnostic push
376#pragma GCC diagnostic ignored "-Winvalid-offsetof"
377#endif
378
379 return reinterpret_cast<BaseEntity*>(reinterpret_cast<std::byte*>(this) - offsetof(BaseEntity, m_values));
380
381#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
382#pragma GCC diagnostic pop
383#endif
384}
385
386template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
388{
389 BaseEntity* owner = GetOwner();
392
393 return { (static_cast<Derived*>(owner)->*field)._value };
394}
395
396template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
398{
399 BaseEntity* owner = GetOwner();
402
403 return { static_cast<Derived*>(owner)->*field };
404}
405
406template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
408{
409 BaseEntity* owner = GetOwner();
412
413 auto& uf = (static_cast<Derived*>(owner)->*field);
414 if (!uf.has_value())
415 uf.ConstructValue();
416
417 return { *uf._value };
418}
419
420template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
422{
423 static_assert(WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject);
424
425 BaseEntity* owner = GetOwner();
426 _changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit);
427
428 (static_cast<Derived*>(owner)->*field)._value.ClearChangesMask();
429}
430
431#endif // TRINITYCORE_BASE_ENTITY_H
std::unordered_map< Player *, UpdateData > UpdateDataMapType
Definition BaseEntity.h:32
LocaleConstant
Definition Common.h:51
#define TC_GAME_API
Definition Define.h:129
uint32_t uint32
Definition Define.h:154
uint16 flags
std::string GetDebugInfo()
Definition Errors.cpp:170
constexpr std::array< uint32, NUM_CLIENT_OBJECT_TYPES+1 > ObjectTypeMask
Definition ObjectGuid.h:85
TypeID
Definition ObjectGuid.h:37
@ TYPEID_AREATRIGGER
Definition ObjectGuid.h:49
@ TYPEID_DYNAMICOBJECT
Definition ObjectGuid.h:47
@ NUM_CLIENT_OBJECT_TYPES
Definition ObjectGuid.h:57
@ TYPEID_GAMEOBJECT
Definition ObjectGuid.h:46
@ TYPEID_UNIT
Definition ObjectGuid.h:43
@ TYPEID_MESH_OBJECT
Definition ObjectGuid.h:52
@ TYPEID_CORPSE
Definition ObjectGuid.h:48
@ TYPEID_SCENEOBJECT
Definition ObjectGuid.h:50
@ TYPEID_CONVERSATION
Definition ObjectGuid.h:51
@ TYPEID_PLAYER
Definition ObjectGuid.h:44
TypeMask
Definition ObjectGuid.h:61
@ TYPEMASK_ITEM
Definition ObjectGuid.h:63
@ TYPEMASK_UNIT
Definition ObjectGuid.h:67
@ TYPEMASK_WORLDOBJECT
Definition ObjectGuid.h:82
Action
bool IsUnit() const
Definition BaseEntity.h:171
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void ApplyPercentModUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, float percent, bool apply)
Definition BaseEntity.h:320
void SetUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
Definition BaseEntity.h:221
WowCS::EntityFragmentsHolder m_entityFragments
Definition BaseEntity.h:353
void SetUpdateFieldStatValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
Definition BaseEntity.h:299
bool IsMeshObject() const
Definition BaseEntity.h:180
BaseEntity & operator=(BaseEntity const &right)=delete
bool IsAreaTrigger() const
Definition BaseEntity.h:177
void ForceUpdateFieldChange(UF::UpdateFieldPrivateSetter< T > const &)
Definition BaseEntity.h:208
void SetDestroyedObject(bool destroyed)
Definition BaseEntity.h:199
bool IsWorldObject() const
Definition BaseEntity.h:169
virtual bool AddToObjectUpdate()=0
void RemoveDynamicUpdateFieldValue(UF::DynamicUpdateFieldSetter< T > setter, uint32 index)
Definition BaseEntity.h:256
void RemoveOptionalUpdateFieldValue(UF::OptionalUpdateFieldSetter< T > setter)
Definition BaseEntity.h:291
UF::UpdateFieldHolder m_values
Definition BaseEntity.h:205
bool IsInWorld() const
Definition BaseEntity.h:158
void _Create(ObjectGuid const &guid)
Definition BaseEntity.h:218
bool isType(TypeMask mask) const
Definition BaseEntity.h:167
BaseEntity(BaseEntity const &right)=delete
void RemoveMapUpdateFieldValue(UF::MapUpdateFieldSetter< K, V > setter, std::type_identity_t< K > const &key)
Definition BaseEntity.h:270
void SetUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type flag)
Definition BaseEntity.h:228
bool IsSceneObject() const
Definition BaseEntity.h:178
void ClearDynamicUpdateFieldValues(UF::DynamicUpdateFieldSetter< T > setter)
Definition BaseEntity.h:263
bool IsDynObject() const
Definition BaseEntity.h:175
bool IsCorpse() const
Definition BaseEntity.h:176
virtual std::string GetNameForLocaleIdx(LocaleConstant locale) const =0
virtual void RemoveFromObjectUpdate()=0
BaseEntity(BaseEntity &&right)=delete
UF::DynamicUpdateFieldSetter< T >::insert_result AddDynamicUpdateFieldValue(UF::DynamicUpdateFieldSetter< T > setter)
Definition BaseEntity.h:242
void SetIsNewObject(bool enable)
Definition BaseEntity.h:197
void RemoveUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type flag)
Definition BaseEntity.h:235
void ApplyModUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type mod, bool apply)
Definition BaseEntity.h:306
static ObjectGuid GetGUID(BaseEntity const *o)
Definition BaseEntity.h:164
bool IsCreature() const
Definition BaseEntity.h:172
void RemoveSetUpdateFieldValue(UF::SetUpdateFieldSetter< T > setter, std::type_identity_t< T > const &key)
Definition BaseEntity.h:284
bool IsGameObject() const
Definition BaseEntity.h:174
bool IsPlayer() const
Definition BaseEntity.h:173
bool IsConversation() const
Definition BaseEntity.h:179
ObjectGuid m_guid
Definition BaseEntity.h:153
bool IsItem() const
Definition BaseEntity.h:170
bool IsDestroyedObject() const
Definition BaseEntity.h:198
void DoWithSuppressingObjectUpdates(Action &&action)
Definition BaseEntity.h:336
UF::DynamicUpdateFieldSetter< T >::insert_result InsertDynamicUpdateFieldValue(UF::DynamicUpdateFieldSetter< T > setter, uint32 index)
Definition BaseEntity.h:249
BaseEntity & operator=(BaseEntity &&right)=delete
void InsertSetUpdateFieldValue(UF::SetUpdateFieldSetter< T > setter, std::type_identity_t< T > const &key)
Definition BaseEntity.h:277
TypeID GetTypeId() const
Definition BaseEntity.h:166
virtual void BuildUpdate(UpdateDataMapType &data_map)
Definition BaseEntity.h:200
static ObjectGuid const Empty
Definition ObjectGuid.h:314
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
MutableFieldReference< T, false > ModifyValue(OptionalUpdateField< T, BlockBit, Bit >(Derived::*field), uint32)
OptionalUpdateFieldSetter< T > ModifyValue(OptionalUpdateField< T, BlockBit, Bit >(Derived::*field))
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
bool HasChanged(uint32 index) const
Definition BaseEntity.h:83
BaseEntity * GetOwner()
Definition BaseEntity.h:372
UpdateFieldHolder()=default
uint32 GetChangedObjectTypeMask() const
Definition BaseEntity.h:81
bool InsertSetUpdateFieldValue(SetUpdateFieldSetter< T > &setter, std::type_identity_t< T > const &key)
Definition BaseEntity.h:133
DynamicUpdateFieldSetter< T >::insert_result AddDynamicUpdateFieldValue(DynamicUpdateFieldSetter< T > &setter)
Definition BaseEntity.h:103
bool RemoveSetUpdateFieldValue(SetUpdateFieldSetter< T > &setter, std::type_identity_t< T > const &key)
Definition BaseEntity.h:139
bool RemoveOptionalUpdateFieldValue(OptionalUpdateFieldSetter< T > &setter)
Definition BaseEntity.h:145
UpdateFieldFlag
Definition UpdateField.h:37
void RemoveDynamicUpdateFieldValue(DynamicUpdateFieldSetter< T > &setter, uint32 index)
Definition BaseEntity.h:115
void ClearDynamicUpdateFieldValues(DynamicUpdateFieldSetter< T > &setter)
Definition BaseEntity.h:121
std::conditional_t< std::is_base_of_v< HasChangesMaskTag, T >, MutableFieldReferenceWithChangesMask< T, PublicSet >, MutableFieldReferenceNoChangesMask< T, PublicSet > > MutableFieldReference
DynamicUpdateFieldSetter< T >::insert_result InsertDynamicUpdateFieldValue(DynamicUpdateFieldSetter< T > &setter, uint32 index)
Definition BaseEntity.h:109
bool SetUpdateFieldValue(UpdateFieldPrivateSetter< T > &setter, typename UpdateFieldPrivateSetter< T >::value_type &&value)
Definition BaseEntity.h:97
bool RemoveMapUpdateFieldValue(MapUpdateFieldSetter< K, V > &setter, std::type_identity_t< K > const &key)
Definition BaseEntity.h:127
constexpr uint32 GetBlockFlag(std::size_t bit)
Definition UpdateMask.h:28
std::conditional_t< std::is_base_of_v< HasChangesMaskTag, T >, MutableFieldReference< T, true >, T & > insert_result
void RemoveValue(std::size_t index)
insert_result InsertValue(std::size_t index)
bool RemoveKey(K const &key)
bool Remove(T const &key)
bool Insert(T const &key)