aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp9
-rw-r--r--src/server/game/Entities/Object/Object.cpp10
-rw-r--r--src/server/game/Entities/Object/Object.h19
-rw-r--r--src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp8
-rw-r--r--src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h4
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