diff options
Diffstat (limited to 'src')
5 files changed, 37 insertions, 13 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 64e7242b34d..c1b6015f87e 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -3668,7 +3668,12 @@ void Creature::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Pl m_unitData->WriteCreate(*data, flags, this, target); if (m_vendorData) + { + if constexpr (WowCS::IsIndirectFragment(WowCS::EntityFragment::FVendor_C)) + *data << uint8(1); // IndirectFragmentActive: FVendor_C + m_vendorData->WriteCreate(*data, flags, this, target); + } } void Creature::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const @@ -3743,8 +3748,6 @@ void Creature::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* pla void Creature::ClearUpdateMask(bool remove) { - if (m_vendorData) - m_values.ClearChangesMask(&Creature::m_vendorData); - + m_values.ClearChangesMask(&Creature::m_vendorData); Unit::ClearUpdateMask(remove); } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a819e0f82e9..30eb3db191e 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -247,11 +247,16 @@ void Object::BuildEntityFragments(ByteBuffer* data, std::span<WowCS::EntityFragm *data << WorldPackets::As<uint8>(WowCS::EntityFragment::End); } -void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag<UF::UpdateFieldFlag> flags) +void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag<UF::UpdateFieldFlag> flags) const { + uint8 contentsChangedMask = WowCS::CGObjectChangedMask; + for (WowCS::EntityFragment updateableFragmentId : m_entityFragments.GetUpdateableIds()) + if (WowCS::IsIndirectFragment(updateableFragmentId)) + contentsChangedMask |= m_entityFragments.GetUpdateMaskFor(updateableFragmentId) >> 1; // set the "fragment exists" bit + *data << uint8(flags.HasFlag(UF::UpdateFieldFlag::Owner)); *data << uint8(false); // m_entityFragments.IdsChanged - *data << uint8(WowCS::CGObjectUpdateMask); + *data << uint8(contentsChangedMask); } void Object::BuildDestroyUpdateBlock(UpdateData* data) const @@ -869,7 +874,6 @@ void Object::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&Object::m_objectData); m_entityFragments.IdsChanged = false; - m_entityFragments.ContentsChangedMask = WowCS::CGObjectActiveMask; if (m_objectUpdated) { diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index ea660a2d243..c55dfe2da85 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -430,7 +430,7 @@ class TC_GAME_API Object virtual void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const = 0; virtual void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const = 0; static void BuildEntityFragments(ByteBuffer* data, std::span<WowCS::EntityFragment const> fragments); - static void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag<UF::UpdateFieldFlag> flags); + void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag<UF::UpdateFieldFlag> flags) const; public: virtual void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const; @@ -520,7 +520,13 @@ inline void UF::UpdateFieldHolder::ClearChangesMask(UpdateField<T, BlockBit, Bit Object* owner = GetOwner(); owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); if constexpr (WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject) + { _changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit); + if (!_changesMask) + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); + } + else + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); (static_cast<Derived*>(owner)->*field)._value.ClearChangesMask(); } @@ -529,11 +535,18 @@ template <typename Derived, typename T, int32 BlockBit, uint32 Bit> inline void UF::UpdateFieldHolder::ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit> Derived::* field) { Object* owner = GetOwner(); - owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); if constexpr (WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject) + { _changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit); + if (!_changesMask) + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); + } + else + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); - (static_cast<Derived*>(owner)->*field)._value->ClearChangesMask(); + auto& uf = (static_cast<Derived*>(owner)->*field); + if (uf.has_value()) + uf._value->ClearChangesMask(); } template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, size_t ARRAY_SIZE> diff --git a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp index 85249caab78..b89d7aab275 100644 --- a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp +++ b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp @@ -56,7 +56,8 @@ void EntityFragmentsHolder::Add(EntityFragment fragment, bool update) if (IsIndirectFragment(UpdateableIds[i])) { ContentsChangedMask |= UpdateableMasks[i]; // set the first bit to true to activate fragment - UpdateableMasks[i] |= 1 << maskIndex++; + ++maskIndex; + UpdateableMasks[i] <<= 1; } } } @@ -96,7 +97,10 @@ void EntityFragmentsHolder::Remove(EntityFragment fragment) { UpdateableMasks[i] = 1 << maskIndex++; if (IsIndirectFragment(UpdateableIds[i])) - UpdateableMasks[i] |= 1 << maskIndex++; + { + ++maskIndex; + UpdateableMasks[i] <<= 1; + } } } } diff --git a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h index dba9e0a11a9..a65ca60978a 100644 --- a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h +++ b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h @@ -51,7 +51,7 @@ enum class EntityFragment : uint8 FEntityLocalMatrix = 113, FEntityWorldMatrix = 114, CActor = 115, // INDIRECT, - FVendor_C = 117, // UPDATEABLE, + FVendor_C = 117, // UPDATEABLE, INDIRECT, FMirroredObject_C = 119, End = 255, }; @@ -63,7 +63,7 @@ inline constexpr bool IsUpdateableFragment(EntityFragment frag) inline constexpr bool IsIndirectFragment(EntityFragment frag) { - return frag == EntityFragment::CGObject || frag == EntityFragment::CActor; + return frag == EntityFragment::CGObject || frag == EntityFragment::CActor || frag == EntityFragment::FVendor_C; } // common case optimization, make use of the fact that fragment arrays are sorted |