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  | 
