18#ifndef TRINITYCORE_BASE_ENTITY_H
19#define TRINITYCORE_BASE_ENTITY_H
25#include <unordered_map>
69 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
72 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
75 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
78 template<
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
99 return setter.
SetValue(std::move(value));
126 template<
typename K,
typename V>
135 return setter.
Insert(key);
141 return setter.
Remove(key);
160 virtual void AddToWorld();
161 virtual void RemoveFromWorld();
182 virtual void BuildCreateUpdateBlockForPlayer(
UpdateData* data,
Player* target)
const;
183 void SendUpdateToPlayer(
Player* player)
const;
185 void BuildValuesUpdateBlockForPlayer(
UpdateData* data,
Player const* target)
const;
186 void BuildDestroyUpdateBlock(
UpdateData* data)
const;
187 void BuildOutOfRangeUpdateBlock(
UpdateData* data)
const;
190 virtual void DestroyForPlayer(
Player const* target)
const;
191 void SendOutOfRangeForPlayer(
Player const* target)
const;
193 void ClearUpdateMask(
bool remove);
201 void BuildUpdateChangesMask();
210 AddToObjectUpdateIfNeeded();
224 AddToObjectUpdateIfNeeded();
230 static_assert(std::is_integral_v<T>,
"SetUpdateFieldFlagValue must be used with integral types");
231 this->SetUpdateFieldValue(setter, setter.
GetValue() | flag);
237 static_assert(std::is_integral_v<T>,
"RemoveUpdateFieldFlagValue must be used with integral types");
238 this->SetUpdateFieldValue(setter, setter.
GetValue() & ~flag);
244 AddToObjectUpdateIfNeeded();
251 AddToObjectUpdateIfNeeded();
258 AddToObjectUpdateIfNeeded();
265 AddToObjectUpdateIfNeeded();
269 template<
typename K,
typename V>
273 AddToObjectUpdateIfNeeded();
280 AddToObjectUpdateIfNeeded();
287 AddToObjectUpdateIfNeeded();
294 AddToObjectUpdateIfNeeded();
301 static_assert(std::is_arithmetic_v<T>,
"SetUpdateFieldStatValue must be used with arithmetic types");
302 this->SetUpdateFieldValue(setter, std::max(value, T(0)));
308 static_assert(std::is_arithmetic_v<T>,
"SetUpdateFieldStatValue must be used with arithmetic types");
316 this->SetUpdateFieldValue(setter, value);
322 static_assert(std::is_arithmetic_v<T>,
"SetUpdateFieldStatValue must be used with arithmetic types");
328 if (percent == -100.0f)
330 value *= (apply ? (100.0f + percent) / 100.0f : 100.0f / (100.0f + percent));
332 this->SetUpdateFieldValue(setter, value);
335 template<
typename Action>
338 bool wasUpdatedBeforeAction = m_objectUpdated;
340 if (m_objectUpdated && !wasUpdatedBeforeAction)
342 RemoveFromObjectUpdate();
343 m_objectUpdated =
false;
349 static void BuildEntityFragments(
ByteBuffer& data, std::span<WowCS::EntityFragment const> fragments);
357 void AddToObjectUpdateIfNeeded();
359 bool m_objectUpdated =
false;
362 bool m_inWorld =
false;
363 bool m_isNewObject =
false;
364 bool m_isDestroyedObject =
false;
374#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
375#pragma GCC diagnostic push
376#pragma GCC diagnostic ignored "-Winvalid-offsetof"
379 return reinterpret_cast<BaseEntity*
>(
reinterpret_cast<std::byte*
>(
this) - offsetof(
BaseEntity, m_values));
381#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
382#pragma GCC diagnostic pop
386template <
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
393 return { (
static_cast<Derived*
>(owner)->*field)._value };
396template <
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
403 return {
static_cast<Derived*
>(owner)->*field };
406template <
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
413 auto& uf = (
static_cast<Derived*
>(owner)->*field);
417 return { *uf._value };
420template <
typename Derived,
typename T,
int32 BlockBit, u
int32 Bit>
428 (
static_cast<Derived*
>(owner)->*field)._value.ClearChangesMask();
std::unordered_map< Player *, UpdateData > UpdateDataMapType
std::string GetDebugInfo()
constexpr std::array< uint32, NUM_CLIENT_OBJECT_TYPES+1 > ObjectTypeMask
@ NUM_CLIENT_OBJECT_TYPES
ObjectGuid const & GetGUID() const
void ApplyPercentModUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, float percent, bool apply)
void SetUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
WowCS::EntityFragmentsHolder m_entityFragments
void SetUpdateFieldStatValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
bool IsMeshObject() const
BaseEntity & operator=(BaseEntity const &right)=delete
bool IsAreaTrigger() const
void ForceUpdateFieldChange(UF::UpdateFieldPrivateSetter< T > const &)
void SetDestroyedObject(bool destroyed)
bool IsWorldObject() const
virtual bool AddToObjectUpdate()=0
void RemoveDynamicUpdateFieldValue(UF::DynamicUpdateFieldSetter< T > setter, uint32 index)
void RemoveOptionalUpdateFieldValue(UF::OptionalUpdateFieldSetter< T > setter)
UF::UpdateFieldHolder m_values
void _Create(ObjectGuid const &guid)
bool isType(TypeMask mask) const
BaseEntity(BaseEntity const &right)=delete
void RemoveMapUpdateFieldValue(UF::MapUpdateFieldSetter< K, V > setter, std::type_identity_t< K > const &key)
void SetUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type flag)
bool IsSceneObject() const
void ClearDynamicUpdateFieldValues(UF::DynamicUpdateFieldSetter< T > setter)
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)
void SetIsNewObject(bool enable)
void RemoveUpdateFieldFlagValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type flag)
void ApplyModUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type mod, bool apply)
static ObjectGuid GetGUID(BaseEntity const *o)
void RemoveSetUpdateFieldValue(UF::SetUpdateFieldSetter< T > setter, std::type_identity_t< T > const &key)
bool IsGameObject() const
bool IsConversation() const
bool IsDestroyedObject() const
void DoWithSuppressingObjectUpdates(Action &&action)
UF::DynamicUpdateFieldSetter< T >::insert_result InsertDynamicUpdateFieldValue(UF::DynamicUpdateFieldSetter< T > setter, uint32 index)
BaseEntity & operator=(BaseEntity &&right)=delete
void InsertSetUpdateFieldValue(UF::SetUpdateFieldSetter< T > setter, std::type_identity_t< T > const &key)
virtual void BuildUpdate(UpdateDataMapType &data_map)
static ObjectGuid const Empty
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
UpdateFieldHolder()=default
uint32 GetChangedObjectTypeMask() const
bool InsertSetUpdateFieldValue(SetUpdateFieldSetter< T > &setter, std::type_identity_t< T > const &key)
DynamicUpdateFieldSetter< T >::insert_result AddDynamicUpdateFieldValue(DynamicUpdateFieldSetter< T > &setter)
bool RemoveSetUpdateFieldValue(SetUpdateFieldSetter< T > &setter, std::type_identity_t< T > const &key)
bool RemoveOptionalUpdateFieldValue(OptionalUpdateFieldSetter< T > &setter)
void RemoveDynamicUpdateFieldValue(DynamicUpdateFieldSetter< T > &setter, uint32 index)
void ClearDynamicUpdateFieldValues(DynamicUpdateFieldSetter< T > &setter)
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)
bool SetUpdateFieldValue(UpdateFieldPrivateSetter< T > &setter, typename UpdateFieldPrivateSetter< T >::value_type &&value)
bool RemoveMapUpdateFieldValue(MapUpdateFieldSetter< K, V > &setter, std::type_identity_t< K > const &key)
constexpr uint32 GetBlockFlag(std::size_t bit)
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)