Core/Objects: Refactor entity fragment functions to separate global array and move ClearChangesMask there

* Additionally unify argument order for UF::Structure::WriteSomething and Object::BuildValuesSomething
This commit is contained in:
Shauren
2026-02-07 13:00:34 +01:00
parent bb21509011
commit 03d05f2cfe
39 changed files with 1657 additions and 1484 deletions

View File

@@ -27,18 +27,12 @@ Account::Account(WorldSession* session, ObjectGuid guid, std::string&& name) : m
{
_Create(guid);
m_entityFragments.Add(WowCS::EntityFragment::FHousingStorage_C, false, WowCS::FragmentSerializationTraits<&Account::m_housingStorageData>{});
m_entityFragments.Add(WowCS::EntityFragment::FHousingStorage_C, false, WowCS::GetRawFragmentData(m_housingStorageData));
// Default value
SetUpdateFieldValue(m_values.ModifyValue(&Account::m_housingStorageData).ModifyValue(&UF::HousingStorageData::DecorMaxOwnedCount), 5000);
}
void Account::ClearUpdateMask(bool remove)
{
m_values.ClearChangesMask(&Account::m_housingStorageData);
BaseEntity::ClearUpdateMask(remove);
}
std::string Account::GetNameForLocaleIdx(LocaleConstant /*locale*/) const
{
return m_name;

View File

@@ -29,8 +29,6 @@ class Account final : public BaseEntity
public:
explicit Account(WorldSession* session, ObjectGuid guid, std::string&& name);
void ClearUpdateMask(bool remove) override;
std::string GetNameForLocaleIdx(LocaleConstant locale) const override;
void BuildUpdate(UpdateDataMapType& data_map) override;

View File

@@ -1498,21 +1498,21 @@ bool AreaTrigger::IsNeverVisibleFor(WorldObject const* seer, bool allowServersid
return false;
}
void AreaTrigger::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AreaTrigger::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_areaTriggerData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_areaTriggerData->WriteCreate(flags, data, target, this);
}
void AreaTrigger::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AreaTrigger::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_AREATRIGGER))
m_areaTriggerData->WriteUpdate(*data, flags, this, target);
m_areaTriggerData->WriteUpdate(flags, data, target, this);
}
void AreaTrigger::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -1529,14 +1529,14 @@ void AreaTrigger::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::Objec
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_AREATRIGGER])
m_areaTriggerData->WriteUpdate(buffer, requestedAreaTriggerMask, true, this, target);
m_areaTriggerData->WriteUpdate(requestedAreaTriggerMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -1554,8 +1554,8 @@ void AreaTrigger::ValuesUpdateForPlayerWithMaskSender::operator()(Player const*
player->SendDirectMessage(&packet);
}
void AreaTrigger::ClearUpdateMask(bool remove)
void AreaTrigger::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&AreaTrigger::m_areaTriggerData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}

View File

@@ -78,9 +78,9 @@ class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject<Area
~AreaTrigger();
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,

View File

@@ -369,21 +369,21 @@ uint32 Conversation::GetScriptId() const
return sConversationDataStore->GetConversationTemplate(GetEntry())->ScriptId;
}
void Conversation::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Conversation::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_conversationData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_conversationData->WriteCreate(flags, data, target, this);
}
void Conversation::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Conversation::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_CONVERSATION))
m_conversationData->WriteUpdate(*data, flags, this, target);
m_conversationData->WriteUpdate(flags, data, target, this);
}
void Conversation::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -400,14 +400,14 @@ void Conversation::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::Obje
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_CONVERSATION])
m_conversationData->WriteUpdate(buffer, requestedConversationMask, true, this, target);
m_conversationData->WriteUpdate(requestedConversationMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -425,8 +425,8 @@ void Conversation::ValuesUpdateForPlayerWithMaskSender::operator()(Player const*
player->SendDirectMessage(&packet);
}
void Conversation::ClearUpdateMask(bool remove)
void Conversation::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Conversation::m_conversationData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}

View File

@@ -33,9 +33,9 @@ class TC_GAME_API Conversation final : public WorldObject, public GridObject<Con
~Conversation();
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,

View File

@@ -239,21 +239,21 @@ bool Corpse::IsExpired(time_t t) const
return m_time < t - 3 * DAY;
}
void Corpse::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Corpse::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_corpseData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_corpseData->WriteCreate(flags, data, target, this);
}
void Corpse::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Corpse::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_CORPSE))
m_corpseData->WriteUpdate(*data, flags, this, target);
m_corpseData->WriteUpdate(flags, data, target, this);
}
void Corpse::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -270,14 +270,14 @@ void Corpse::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_CORPSE])
m_corpseData->WriteUpdate(buffer, requestedCorpseMask, true, this, target);
m_corpseData->WriteUpdate(requestedCorpseMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -295,8 +295,8 @@ void Corpse::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* playe
player->SendDirectMessage(&packet);
}
void Corpse::ClearUpdateMask(bool remove)
void Corpse::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Corpse::m_corpseData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}

View File

@@ -56,9 +56,9 @@ class TC_GAME_API Corpse final : public WorldObject, public GridObject<Corpse>
~Corpse();
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,

View File

@@ -3304,11 +3304,13 @@ void Creature::SetVendor(NPCFlags flags, bool apply)
VendorDataTypeFlags vendorFlags = static_cast<VendorDataTypeFlags>(AsUnderlyingType(flags) >> 7);
if (apply)
{
if (!m_vendorData)
m_entityFragments.Add(WowCS::EntityFragment::FVendor_C, IsInWorld(), WowCS::FragmentSerializationTraits<&Creature::m_vendorData>{});
bool addFragment = !m_vendorData.has_value();
SetNpcFlag(flags);
SetUpdateFieldFlagValue(m_values.ModifyValue(&Creature::m_vendorData, 0).ModifyValue(&UF::VendorData::Flags), AsUnderlyingType(vendorFlags));
if (addFragment)
m_entityFragments.Add(WowCS::EntityFragment::FVendor_C, IsInWorld(), WowCS::GetRawFragmentData(m_vendorData));
}
else if (m_vendorData)
{
@@ -3326,11 +3328,13 @@ void Creature::SetPetitioner(bool apply)
{
if (apply)
{
if (!m_vendorData)
m_entityFragments.Add(WowCS::EntityFragment::FVendor_C, IsInWorld(), WowCS::FragmentSerializationTraits<&Creature::m_vendorData>{});
bool addFragment = !m_vendorData.has_value();
SetNpcFlag(UNIT_NPC_FLAG_PETITIONER);
SetUpdateFieldFlagValue(m_values.ModifyValue(&Creature::m_vendorData, 0).ModifyValue(&UF::VendorData::Flags), AsUnderlyingType(VendorDataTypeFlags::Petition));
if (addFragment)
m_entityFragments.Add(WowCS::EntityFragment::FVendor_C, IsInWorld(), WowCS::GetRawFragmentData(m_vendorData));
}
else if (m_vendorData)
{
@@ -3872,33 +3876,33 @@ void Creature::InitializeInteractSpellId()
SetInteractSpellId(0);
}
void Creature::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Creature::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_unitData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_unitData->WriteCreate(flags, data, target, this);
}
void Creature::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Creature::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_UNIT))
m_unitData->WriteUpdate(*data, flags, this, target);
m_unitData->WriteUpdate(flags, data, target, this);
}
void Creature::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Creature::BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask;
valuesMask.Set(TYPEID_UNIT);
*data << uint32(valuesMask.GetBlock(0));
data << uint32(valuesMask.GetBlock(0));
UF::UnitData::Mask mask;
m_unitData->AppendAllowedFieldsMaskForFlag(mask, flags);
m_unitData->WriteUpdate(*data, mask, true, this, target);
UF::UnitData::AppendAllowedFieldsMaskForFlag(mask, flags);
m_unitData->WriteUpdate(mask, data, target, this, true);
}
void Creature::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -3910,21 +3914,21 @@ void Creature::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectDa
valuesMask.Set(TYPEID_OBJECT);
UF::UnitData::Mask unitMask = requestedUnitMask;
m_unitData->FilterDisallowedFieldsMaskForFlag(unitMask, flags);
UF::UnitData::FilterDisallowedFieldsMaskForFlag(unitMask, flags);
if (unitMask.IsAnySet())
valuesMask.Set(TYPEID_UNIT);
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_UNIT])
m_unitData->WriteUpdate(buffer, unitMask, true, this, target);
m_unitData->WriteUpdate(unitMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -3941,9 +3945,3 @@ void Creature::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* pla
udata.BuildPacket(&packet);
player->SendDirectMessage(&packet);
}
void Creature::ClearUpdateMask(bool remove)
{
m_values.ClearChangesMask(&Creature::m_vendorData);
Unit::ClearUpdateMask(remove);
}

View File

@@ -492,11 +492,11 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
UF::OptionalUpdateField<UF::VendorData, int32(WowCS::EntityFragment::FVendor_C), 0> m_vendorData;
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
public:
void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
UF::UnitData::Mask const& requestedUnitMask, Player const* target) const;
@@ -512,8 +512,6 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
};
protected:
void ClearUpdateMask(bool remove) override;
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, CreatureData const* data = nullptr, uint32 vehId = 0);
bool InitEntry(uint32 entry, CreatureData const* data = nullptr);

View File

@@ -248,21 +248,21 @@ SpellInfo const* DynamicObject::GetSpellInfo() const
return sSpellMgr->GetSpellInfo(GetSpellId(), GetMap()->GetDifficultyID());
}
void DynamicObject::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void DynamicObject::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_dynamicObjectData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_dynamicObjectData->WriteCreate(flags, data, target, this);
}
void DynamicObject::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void DynamicObject::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_DYNAMICOBJECT))
m_dynamicObjectData->WriteUpdate(*data, flags, this, target);
m_dynamicObjectData->WriteUpdate(flags, data, target, this);
}
void DynamicObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -279,14 +279,14 @@ void DynamicObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::Obj
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_DYNAMICOBJECT])
m_dynamicObjectData->WriteUpdate(buffer, requestedDynamicObjectMask, true, this, target);
m_dynamicObjectData->WriteUpdate(requestedDynamicObjectMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -304,8 +304,8 @@ void DynamicObject::ValuesUpdateForPlayerWithMaskSender::operator()(Player const
player->SendDirectMessage(&packet);
}
void DynamicObject::ClearUpdateMask(bool remove)
void DynamicObject::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&DynamicObject::m_dynamicObjectData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}

View File

@@ -40,9 +40,9 @@ class TC_GAME_API DynamicObject final : public WorldObject, public GridObject<Dy
~DynamicObject();
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,

View File

@@ -4074,21 +4074,21 @@ GameObject* GameObject::GetLinkedTrap()
return ObjectAccessor::GetGameObject(*this, m_linkedTrap);
}
void GameObject::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void GameObject::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_gameObjectData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_gameObjectData->WriteCreate(flags, data, target, this);
}
void GameObject::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void GameObject::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_GAMEOBJECT))
m_gameObjectData->WriteUpdate(*data, flags, this, target);
m_gameObjectData->WriteUpdate(flags, data, target, this);
}
void GameObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -4105,14 +4105,14 @@ void GameObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::Object
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_GAMEOBJECT])
m_gameObjectData->WriteUpdate(buffer, requestedGameObjectMask, true, this, target);
m_gameObjectData->WriteUpdate(requestedGameObjectMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -4130,10 +4130,10 @@ void GameObject::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* p
player->SendDirectMessage(&packet);
}
void GameObject::ClearUpdateMask(bool remove)
void GameObject::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&GameObject::m_gameObjectData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}
std::span<uint32 const> GameObject::GetPauseTimes() const

View File

@@ -169,9 +169,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
~GameObject();
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,

View File

@@ -155,25 +155,25 @@ int64 AzeriteEmpoweredItem::GetRespecCost() const
return MAX_MONEY_AMOUNT + 1;
}
void AzeriteEmpoweredItem::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AzeriteEmpoweredItem::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_itemData->WriteCreate(*data, flags, this, target);
m_azeriteEmpoweredItemData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_itemData->WriteCreate(flags, data, target, this);
m_azeriteEmpoweredItemData->WriteCreate(flags, data, target, this);
}
void AzeriteEmpoweredItem::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AzeriteEmpoweredItem::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_ITEM))
m_itemData->WriteUpdate(*data, flags, this, target);
m_itemData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_AZERITE_EMPOWERED_ITEM))
m_azeriteEmpoweredItemData->WriteUpdate(*data, flags, this, target);
m_azeriteEmpoweredItemData->WriteUpdate(flags, data, target, this);
}
void AzeriteEmpoweredItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -185,7 +185,7 @@ void AzeriteEmpoweredItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data,
valuesMask.Set(TYPEID_OBJECT);
UF::ItemData::Mask itemMask = requestedItemMask;
m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags);
UF::ItemData::FilterDisallowedFieldsMaskForFlag(itemMask, flags);
if (itemMask.IsAnySet())
valuesMask.Set(TYPEID_ITEM);
@@ -195,17 +195,17 @@ void AzeriteEmpoweredItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data,
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_ITEM])
m_itemData->WriteUpdate(buffer, itemMask, true, this, target);
m_itemData->WriteUpdate(itemMask, buffer, target, this, true);
if (valuesMask[TYPEID_AZERITE_EMPOWERED_ITEM])
m_azeriteEmpoweredItemData->WriteUpdate(buffer, requestedAzeriteEmpoweredItemMask, true, this, target);
m_azeriteEmpoweredItemData->WriteUpdate(requestedAzeriteEmpoweredItemMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -223,10 +223,10 @@ void AzeriteEmpoweredItem::ValuesUpdateForPlayerWithMaskSender::operator()(Playe
player->SendDirectMessage(&packet);
}
void AzeriteEmpoweredItem::ClearUpdateMask(bool remove)
void AzeriteEmpoweredItem::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData);
Item::ClearUpdateMask(remove);
Item::ClearValuesChangesMask();
}
void AzeriteEmpoweredItem::InitAzeritePowerData()

View File

@@ -43,9 +43,9 @@ public:
int64 GetRespecCost() const;
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask,

View File

@@ -390,42 +390,42 @@ void AzeriteItem::SetSelectedAzeriteEssence(uint8 slot, uint32 azeriteEssenceId)
.ModifyValue(&UF::SelectedAzeriteEssences::AzeriteEssenceID, slot), azeriteEssenceId);
}
void AzeriteItem::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AzeriteItem::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_itemData->WriteCreate(*data, flags, this, target);
m_azeriteItemData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_itemData->WriteCreate(flags, data, target, this);
m_azeriteItemData->WriteCreate(flags, data, target, this);
}
void AzeriteItem::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AzeriteItem::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_ITEM))
m_itemData->WriteUpdate(*data, flags, this, target);
m_itemData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_AZERITE_ITEM))
m_azeriteItemData->WriteUpdate(*data, flags, this, target);
m_azeriteItemData->WriteUpdate(flags, data, target, this);
}
void AzeriteItem::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void AzeriteItem::BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask;
valuesMask.Set(TYPEID_ITEM);
valuesMask.Set(TYPEID_AZERITE_ITEM);
*data << uint32(valuesMask.GetBlock(0));
data << uint32(valuesMask.GetBlock(0));
UF::ItemData::Mask mask;
m_itemData->AppendAllowedFieldsMaskForFlag(mask, flags);
m_itemData->WriteUpdate(*data, mask, true, this, target);
UF::ItemData::AppendAllowedFieldsMaskForFlag(mask, flags);
m_itemData->WriteUpdate(mask, data, target, this, true);
UF::AzeriteItemData::Mask mask2;
m_azeriteItemData->AppendAllowedFieldsMaskForFlag(mask2, flags);
m_azeriteItemData->WriteUpdate(*data, mask2, true, this, target);
UF::AzeriteItemData::AppendAllowedFieldsMaskForFlag(mask2, flags);
m_azeriteItemData->WriteUpdate(mask2, data, target, this, true);
}
void AzeriteItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -437,29 +437,29 @@ void AzeriteItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::Objec
valuesMask.Set(TYPEID_OBJECT);
UF::ItemData::Mask itemMask = requestedItemMask;
m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags);
UF::ItemData::FilterDisallowedFieldsMaskForFlag(itemMask, flags);
if (itemMask.IsAnySet())
valuesMask.Set(TYPEID_ITEM);
UF::AzeriteItemData::Mask azeriteItemMask = requestedAzeriteItemMask;
m_azeriteItemData->FilterDisallowedFieldsMaskForFlag(azeriteItemMask, flags);
UF::AzeriteItemData::FilterDisallowedFieldsMaskForFlag(azeriteItemMask, flags);
if (azeriteItemMask.IsAnySet())
valuesMask.Set(TYPEID_AZERITE_ITEM);
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_ITEM])
m_itemData->WriteUpdate(buffer, itemMask, true, this, target);
m_itemData->WriteUpdate(itemMask, buffer, target, this, true);
if (valuesMask[TYPEID_AZERITE_ITEM])
m_azeriteItemData->WriteUpdate(buffer, azeriteItemMask, true, this, target);
m_azeriteItemData->WriteUpdate(azeriteItemMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -477,10 +477,10 @@ void AzeriteItem::ValuesUpdateForPlayerWithMaskSender::operator()(Player const*
player->SendDirectMessage(&packet);
}
void AzeriteItem::ClearUpdateMask(bool remove)
void AzeriteItem::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&AzeriteItem::m_azeriteItemData);
Item::ClearUpdateMask(remove);
Item::ClearValuesChangesMask();
}
void AzeriteItem::UnlockDefaultMilestones()

View File

@@ -74,12 +74,12 @@ public:
void SetSelectedAzeriteEssence(uint8 slot, uint32 azeriteEssenceId);
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask,
UF::AzeriteItemData::Mask const& requestedAzeriteItemMask, Player const* target) const;

View File

@@ -183,25 +183,25 @@ void Bag::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) cons
m_bagslot[i]->BuildCreateUpdateBlockForPlayer(data, target);
}
void Bag::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Bag::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_itemData->WriteCreate(*data, flags, this, target);
m_containerData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_itemData->WriteCreate(flags, data, target, this);
m_containerData->WriteCreate(flags, data, target, this);
}
void Bag::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Bag::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_ITEM))
m_itemData->WriteUpdate(*data, flags, this, target);
m_itemData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_CONTAINER))
m_containerData->WriteUpdate(*data, flags, this, target);
m_containerData->WriteUpdate(flags, data, target, this);
}
void Bag::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -213,7 +213,7 @@ void Bag::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::M
valuesMask.Set(TYPEID_OBJECT);
UF::ItemData::Mask itemMask = requestedItemMask;
m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags);
UF::ItemData::FilterDisallowedFieldsMaskForFlag(itemMask, flags);
if (itemMask.IsAnySet())
valuesMask.Set(TYPEID_ITEM);
@@ -223,17 +223,17 @@ void Bag::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::M
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_ITEM])
m_itemData->WriteUpdate(buffer, itemMask, true, this, target);
m_itemData->WriteUpdate(itemMask, buffer, target, this, true);
if (valuesMask[TYPEID_CONTAINER])
m_containerData->WriteUpdate(buffer, requestedContainerMask, true, this, target);
m_containerData->WriteUpdate(requestedContainerMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -251,10 +251,10 @@ void Bag::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* player)
player->SendDirectMessage(&packet);
}
void Bag::ClearUpdateMask(bool remove)
void Bag::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Bag::m_containerData);
Item::ClearUpdateMask(remove);
Item::ClearValuesChangesMask();
}
// If the bag is empty returns true

View File

@@ -54,9 +54,9 @@ class TC_GAME_API Bag : public Item
protected:
void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override;
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask,

View File

@@ -1803,33 +1803,33 @@ UF::UpdateFieldFlag Item::GetUpdateFieldFlagsFor(Player const* target) const
return UF::UpdateFieldFlag::None;
}
void Item::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Item::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_itemData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_itemData->WriteCreate(flags, data, target, this);
}
void Item::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Item::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_ITEM))
m_itemData->WriteUpdate(*data, flags, this, target);
m_itemData->WriteUpdate(flags, data, target, this);
}
void Item::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Item::BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask;
valuesMask.Set(TYPEID_ITEM);
*data << uint32(valuesMask.GetBlock(0));
data << uint32(valuesMask.GetBlock(0));
UF::ItemData::Mask mask;
m_itemData->AppendAllowedFieldsMaskForFlag(mask, flags);
m_itemData->WriteUpdate(*data, mask, true, this, target);
UF::ItemData::AppendAllowedFieldsMaskForFlag(mask, flags);
m_itemData->WriteUpdate(mask, data, target, this, true);
}
void Item::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -1841,21 +1841,21 @@ void Item::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::
valuesMask.Set(TYPEID_OBJECT);
UF::ItemData::Mask itemMask = requestedItemMask;
m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags);
UF::ItemData::FilterDisallowedFieldsMaskForFlag(itemMask, flags);
if (itemMask.IsAnySet())
valuesMask.Set(TYPEID_ITEM);
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_ITEM])
m_itemData->WriteUpdate(buffer, itemMask, true, this, target);
m_itemData->WriteUpdate(itemMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -1873,10 +1873,10 @@ void Item::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* player)
player->SendDirectMessage(&packet);
}
void Item::ClearUpdateMask(bool remove)
void Item::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Item::m_itemData);
Object::ClearUpdateMask(remove);
Object::ClearValuesChangesMask();
}
bool Item::AddToObjectUpdate()

View File

@@ -387,12 +387,12 @@ class TC_GAME_API Item : public Object
protected:
UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const final;
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
UF::ItemData::Mask const& requestedItemMask, Player const* target) const;

View File

@@ -28,6 +28,30 @@
#include "UpdateData.h"
#include "Vehicle.h"
namespace WowCS
{
struct FragmentInfoInitializer
{
FragmentInfoInitializer()
{
EntityFragmentInfos::Register(EntityFragment::FVendor_C, WowCS::FragmentSerializationTraits<UF::VendorData>{});
EntityFragmentInfos::Register(EntityFragment::FMeshObjectData_C, WowCS::FragmentSerializationTraits<UF::MeshObjectData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingDecor_C, WowCS::FragmentSerializationTraits<UF::HousingDecorData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingRoom_C, WowCS::FragmentSerializationTraits<UF::HousingRoomData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingRoomComponentMesh_C, WowCS::FragmentSerializationTraits<UF::HousingRoomComponentMeshData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingPlayerHouse_C, WowCS::FragmentSerializationTraits<UF::HousingPlayerHouseData>{});
EntityFragmentInfos::Register(EntityFragment::FJamHousingCornerstone_C, WowCS::FragmentSerializationTraits<UF::HousingCornerstoneData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingPlotAreaTrigger_C, WowCS::FragmentSerializationTraits<UF::HousingPlotAreaTriggerData>{});
EntityFragmentInfos::Register(EntityFragment::FNeighborhoodMirrorData_C, WowCS::FragmentSerializationTraits<UF::NeighborhoodMirrorData>{});
EntityFragmentInfos::Register(EntityFragment::FMirroredPositionData_C, WowCS::FragmentSerializationTraits<UF::MirroredPositionData>{});
EntityFragmentInfos::Register(EntityFragment::PlayerHouseInfoComponent_C, WowCS::FragmentSerializationTraits<UF::PlayerHouseInfoComponentData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingStorage_C, WowCS::FragmentSerializationTraits<UF::HousingStorageData>{});
EntityFragmentInfos::Register(EntityFragment::FHousingFixture_C, WowCS::FragmentSerializationTraits<UF::HousingFixtureData>{});
EntityFragmentInfos::Register(EntityFragment::PlayerInitiativeComponent_C, WowCS::FragmentSerializationTraits<UF::PlayerInitiativeComponentData>{});
}
} static InitFragments;
}
BaseEntity::BaseEntity() = default;
BaseEntity::~BaseEntity()
@@ -96,13 +120,13 @@ void BaseEntity::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* targe
buf << GetGUID();
buf << uint8(objectType);
BuildMovementUpdate(&buf, flags, target);
BuildMovementUpdate(buf, flags, target);
UF::UpdateFieldFlag fieldFlags = GetUpdateFieldFlagsFor(target);
std::size_t sizePos = buf.wpos();
buf << uint32(0);
buf << uint8(fieldFlags);
BuildEntityFragments(&buf, m_entityFragments.GetIds());
BuildEntityFragments(buf, m_entityFragments.GetIds());
for (std::size_t i = 0; i < m_entityFragments.UpdateableCount; ++i)
{
@@ -110,7 +134,8 @@ void BaseEntity::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* targe
if (WowCS::IsIndirectFragment(fragmentId))
buf << uint8(1); // IndirectFragmentActive
m_entityFragments.Updateable.SerializeCreate[i](this, buf, fieldFlags, target);
WowCS::EntityFragmentInfo->SerializeCreate[static_cast<std::size_t>(m_entityFragments.Updateable.Ids[i])](
m_entityFragments.Updateable.Data[i], fieldFlags, buf, target, this);
}
buf.put<uint32>(sizePos, buf.wpos() - sizePos - 4);
@@ -144,7 +169,7 @@ void BaseEntity::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const*
if (m_entityFragments.IdsChanged)
{
buf << uint8(WowCS::EntityFragmentSerializationType::Full);
BuildEntityFragments(&buf, m_entityFragments.GetIds());
BuildEntityFragments(buf, m_entityFragments.GetIds());
}
buf << uint8(m_entityFragments.ContentsChangedMask);
@@ -153,7 +178,8 @@ void BaseEntity::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const*
if (!(m_entityFragments.ContentsChangedMask & m_entityFragments.Updateable.Masks[i]))
continue;
m_entityFragments.Updateable.SerializeUpdate[i](this, buf, fieldFlags, target);
WowCS::EntityFragmentInfo->SerializeUpdate[static_cast<std::size_t>(m_entityFragments.Updateable.Ids[i])](
m_entityFragments.Updateable.Data[i], fieldFlags, buf, target, this);
}
buf.put<uint32>(sizePos, buf.wpos() - sizePos - 4);
@@ -161,10 +187,10 @@ void BaseEntity::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const*
data->AddUpdateBlock();
}
inline void BaseEntity::BuildEntityFragments(ByteBuffer* data, std::span<WowCS::EntityFragment const> fragments)
inline void BaseEntity::BuildEntityFragments(ByteBuffer& data, std::span<WowCS::EntityFragment const> fragments)
{
data->append(fragments.data(), fragments.size());
*data << uint8(WowCS::EntityFragment::End);
data.append(fragments.data(), fragments.size());
data << uint8(WowCS::EntityFragment::End);
}
void BaseEntity::BuildDestroyUpdateBlock(UpdateData* data) const
@@ -207,34 +233,34 @@ void BaseEntity::SendOutOfRangeForPlayer(Player const* target) const
target->SendDirectMessage(&packet);
}
void BaseEntity::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Player const* target) const
void BaseEntity::BuildMovementUpdate(ByteBuffer& data, CreateObjectBits flags, Player const* target) const
{
std::span<uint32 const> PauseTimes;
if (IsGameObject())
PauseTimes = static_cast<GameObject const*>(this)->GetPauseTimes();
data->WriteBit(flags.HasEntityPosition);
data->WriteBit(flags.NoBirthAnim);
data->WriteBit(flags.EnablePortals);
data->WriteBit(flags.PlayHoverAnim);
data->WriteBit(flags.ThisIsYou);
data->WriteBit(flags.MovementUpdate);
data->WriteBit(flags.MovementTransport);
data->WriteBit(flags.Stationary);
data->WriteBit(flags.CombatVictim);
data->WriteBit(flags.ServerTime);
data->WriteBit(flags.Vehicle);
data->WriteBit(flags.AnimKit);
data->WriteBit(flags.Rotation);
data->WriteBit(flags.GameObject);
data->WriteBit(flags.SmoothPhasing);
data->WriteBit(flags.SceneObject);
data->WriteBit(flags.ActivePlayer);
data->WriteBit(flags.Conversation);
data->WriteBit(flags.Room);
data->WriteBit(flags.Decor);
data->WriteBit(flags.MeshObject);
data->FlushBits();
data.WriteBit(flags.HasEntityPosition);
data.WriteBit(flags.NoBirthAnim);
data.WriteBit(flags.EnablePortals);
data.WriteBit(flags.PlayHoverAnim);
data.WriteBit(flags.ThisIsYou);
data.WriteBit(flags.MovementUpdate);
data.WriteBit(flags.MovementTransport);
data.WriteBit(flags.Stationary);
data.WriteBit(flags.CombatVictim);
data.WriteBit(flags.ServerTime);
data.WriteBit(flags.Vehicle);
data.WriteBit(flags.AnimKit);
data.WriteBit(flags.Rotation);
data.WriteBit(flags.GameObject);
data.WriteBit(flags.SmoothPhasing);
data.WriteBit(flags.SceneObject);
data.WriteBit(flags.ActivePlayer);
data.WriteBit(flags.Conversation);
data.WriteBit(flags.Room);
data.WriteBit(flags.Decor);
data.WriteBit(flags.MeshObject);
data.FlushBits();
if (flags.MovementUpdate)
{
@@ -247,191 +273,191 @@ void BaseEntity::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, P
bool HasDriveStatus = unit->m_movementInfo.driveStatus.has_value();
bool HasStandingOnGameObjectGUID = unit->m_movementInfo.standingOnGameObjectGUID.has_value();
*data << GetGUID(); // MoverGUID
data << GetGUID(); // MoverGUID
*data << uint32(unit->GetUnitMovementFlags());
*data << uint32(unit->GetExtraUnitMovementFlags());
*data << uint32(unit->GetExtraUnitMovementFlags2());
data << uint32(unit->GetUnitMovementFlags());
data << uint32(unit->GetExtraUnitMovementFlags());
data << uint32(unit->GetExtraUnitMovementFlags2());
*data << uint32(unit->m_movementInfo.time); // MoveTime
*data << float(unit->GetPositionX());
*data << float(unit->GetPositionY());
*data << float(unit->GetPositionZ());
*data << float(unit->GetOrientation());
data << uint32(unit->m_movementInfo.time); // MoveTime
data << float(unit->GetPositionX());
data << float(unit->GetPositionY());
data << float(unit->GetPositionZ());
data << float(unit->GetOrientation());
*data << float(unit->m_movementInfo.pitch); // Pitch
*data << float(unit->m_movementInfo.stepUpStartElevation); // StepUpStartElevation
data << float(unit->m_movementInfo.pitch); // Pitch
data << float(unit->m_movementInfo.stepUpStartElevation); // StepUpStartElevation
*data << uint32(0); // RemoveForcesIDs.size()
*data << uint32(0); // MoveIndex
data << uint32(0); // RemoveForcesIDs.size()
data << uint32(0); // MoveIndex
*data << float(unit->m_movementInfo.gravityModifier);
data << float(unit->m_movementInfo.gravityModifier);
//for (std::size_t i = 0; i < RemoveForcesIDs.size(); ++i)
// *data << ObjectGuid(RemoveForcesIDs);
// data << ObjectGuid(RemoveForcesIDs);
data->WriteBit(HasStandingOnGameObjectGUID); // HasStandingOnGameObjectGUID
data->WriteBit(!unit->m_movementInfo.transport.guid.IsEmpty()); // HasTransport
data->WriteBit(HasFall); // HasFall
data->WriteBit(HasSpline); // HasSpline - marks that the unit uses spline movement
data->WriteBit(false); // HeightChangeFailed
data->WriteBit(false); // RemoteTimeValid
data->WriteBit(HasInertia); // HasInertia
data->WriteBit(HasAdvFlying); // HasAdvFlying
data->WriteBit(HasDriveStatus); // HasDriveStatus
data->FlushBits();
data.WriteBit(HasStandingOnGameObjectGUID); // HasStandingOnGameObjectGUID
data.WriteBit(!unit->m_movementInfo.transport.guid.IsEmpty()); // HasTransport
data.WriteBit(HasFall); // HasFall
data.WriteBit(HasSpline); // HasSpline - marks that the unit uses spline movement
data.WriteBit(false); // HeightChangeFailed
data.WriteBit(false); // RemoteTimeValid
data.WriteBit(HasInertia); // HasInertia
data.WriteBit(HasAdvFlying); // HasAdvFlying
data.WriteBit(HasDriveStatus); // HasDriveStatus
data.FlushBits();
if (!unit->m_movementInfo.transport.guid.IsEmpty())
*data << unit->m_movementInfo.transport;
data << unit->m_movementInfo.transport;
if (HasStandingOnGameObjectGUID)
*data << *unit->m_movementInfo.standingOnGameObjectGUID;
data << *unit->m_movementInfo.standingOnGameObjectGUID;
if (HasInertia)
{
*data << unit->m_movementInfo.inertia->id;
*data << unit->m_movementInfo.inertia->force.PositionXYZStream();
*data << uint32(unit->m_movementInfo.inertia->lifetime);
data << unit->m_movementInfo.inertia->id;
data << unit->m_movementInfo.inertia->force.PositionXYZStream();
data << uint32(unit->m_movementInfo.inertia->lifetime);
}
if (HasAdvFlying)
{
*data << float(unit->m_movementInfo.advFlying->forwardVelocity);
*data << float(unit->m_movementInfo.advFlying->upVelocity);
data << float(unit->m_movementInfo.advFlying->forwardVelocity);
data << float(unit->m_movementInfo.advFlying->upVelocity);
}
if (HasFall)
{
*data << uint32(unit->m_movementInfo.jump.fallTime); // Time
*data << float(unit->m_movementInfo.jump.zspeed); // JumpVelocity
data << uint32(unit->m_movementInfo.jump.fallTime); // Time
data << float(unit->m_movementInfo.jump.zspeed); // JumpVelocity
if (data->WriteBit(HasFallDirection))
if (data.WriteBit(HasFallDirection))
{
*data << float(unit->m_movementInfo.jump.sinAngle); // Direction
*data << float(unit->m_movementInfo.jump.cosAngle);
*data << float(unit->m_movementInfo.jump.xyspeed); // Speed
data << float(unit->m_movementInfo.jump.sinAngle); // Direction
data << float(unit->m_movementInfo.jump.cosAngle);
data << float(unit->m_movementInfo.jump.xyspeed); // Speed
}
}
if (HasDriveStatus)
{
*data << float(unit->m_movementInfo.driveStatus->speed);
*data << float(unit->m_movementInfo.driveStatus->movementAngle);
data->WriteBit(unit->m_movementInfo.driveStatus->accelerating);
data->WriteBit(unit->m_movementInfo.driveStatus->drifting);
data->FlushBits();
data << float(unit->m_movementInfo.driveStatus->speed);
data << float(unit->m_movementInfo.driveStatus->movementAngle);
data.WriteBit(unit->m_movementInfo.driveStatus->accelerating);
data.WriteBit(unit->m_movementInfo.driveStatus->drifting);
data.FlushBits();
}
*data << float(unit->GetSpeed(MOVE_WALK));
*data << float(unit->GetSpeed(MOVE_RUN));
*data << float(unit->GetSpeed(MOVE_RUN_BACK));
*data << float(unit->GetSpeed(MOVE_SWIM));
*data << float(unit->GetSpeed(MOVE_SWIM_BACK));
*data << float(unit->GetSpeed(MOVE_FLIGHT));
*data << float(unit->GetSpeed(MOVE_FLIGHT_BACK));
*data << float(unit->GetSpeed(MOVE_TURN_RATE));
*data << float(unit->GetSpeed(MOVE_PITCH_RATE));
data << float(unit->GetSpeed(MOVE_WALK));
data << float(unit->GetSpeed(MOVE_RUN));
data << float(unit->GetSpeed(MOVE_RUN_BACK));
data << float(unit->GetSpeed(MOVE_SWIM));
data << float(unit->GetSpeed(MOVE_SWIM_BACK));
data << float(unit->GetSpeed(MOVE_FLIGHT));
data << float(unit->GetSpeed(MOVE_FLIGHT_BACK));
data << float(unit->GetSpeed(MOVE_TURN_RATE));
data << float(unit->GetSpeed(MOVE_PITCH_RATE));
if (MovementForces const* movementForces = unit->GetMovementForces())
{
*data << uint32(movementForces->GetForces()->size());
*data << float(movementForces->GetModMagnitude()); // MovementForcesModMagnitude
data << uint32(movementForces->GetForces()->size());
data << float(movementForces->GetModMagnitude()); // MovementForcesModMagnitude
}
else
{
*data << uint32(0);
*data << float(1.0f); // MovementForcesModMagnitude
data << uint32(0);
data << float(1.0f); // MovementForcesModMagnitude
}
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_AIR_FRICTION));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_MAX_VEL));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_LIFT_COEFFICIENT));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_DOUBLE_JUMP_VEL_MOD));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_GLIDE_START_MIN_HEIGHT));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_ADD_IMPULSE_MAX_SPEED));
*data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_BANKING_RATE));
*data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_BANKING_RATE));
*data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_PITCHING_RATE_DOWN));
*data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_PITCHING_RATE_DOWN));
*data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_PITCHING_RATE_UP));
*data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_PITCHING_RATE_UP));
*data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_TURN_VELOCITY_THRESHOLD));
*data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_TURN_VELOCITY_THRESHOLD));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_SURFACE_FRICTION));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_OVER_MAX_DECELERATION));
*data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_LAUNCH_SPEED_COEFFICIENT));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_AIR_FRICTION));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_MAX_VEL));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_LIFT_COEFFICIENT));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_DOUBLE_JUMP_VEL_MOD));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_GLIDE_START_MIN_HEIGHT));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_ADD_IMPULSE_MAX_SPEED));
data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_BANKING_RATE));
data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_BANKING_RATE));
data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_PITCHING_RATE_DOWN));
data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_PITCHING_RATE_DOWN));
data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_PITCHING_RATE_UP));
data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_PITCHING_RATE_UP));
data << float(unit->GetAdvFlyingSpeedMin(ADV_FLYING_TURN_VELOCITY_THRESHOLD));
data << float(unit->GetAdvFlyingSpeedMax(ADV_FLYING_TURN_VELOCITY_THRESHOLD));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_SURFACE_FRICTION));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_OVER_MAX_DECELERATION));
data << float(unit->GetAdvFlyingSpeed(ADV_FLYING_LAUNCH_SPEED_COEFFICIENT));
data->WriteBit(HasSpline);
data->FlushBits();
data.WriteBit(HasSpline);
data.FlushBits();
if (MovementForces const* movementForces = unit->GetMovementForces())
for (MovementForce const& force : *movementForces->GetForces())
WorldPackets::Movement::CommonMovement::WriteMovementForceWithDirection(force, *data, unit);
WorldPackets::Movement::CommonMovement::WriteMovementForceWithDirection(force, data, unit);
if (HasSpline)
WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(*unit->movespline, *data);
WorldPackets::Movement::CommonMovement::WriteCreateObjectSplineDataBlock(*unit->movespline, data);
}
*data << uint32(PauseTimes.size());
data << uint32(PauseTimes.size());
if (flags.Stationary)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
*data << self->GetStationaryPosition().PositionXYZOStream();
data << self->GetStationaryPosition().PositionXYZOStream();
}
if (flags.CombatVictim)
{
Unit const* unit = static_cast<Unit const*>(this);
*data << unit->GetVictim()->GetGUID(); // CombatVictim
data << unit->GetVictim()->GetGUID(); // CombatVictim
}
if (flags.ServerTime)
*data << uint32(GameTime::GetGameTimeMS());
data << uint32(GameTime::GetGameTimeMS());
if (flags.Vehicle)
{
Unit const* unit = static_cast<Unit const*>(this);
*data << uint32(unit->GetVehicleKit()->GetVehicleInfo()->ID); // RecID
*data << float(unit->GetOrientation()); // InitialRawFacing
data << uint32(unit->GetVehicleKit()->GetVehicleInfo()->ID); // RecID
data << float(unit->GetOrientation()); // InitialRawFacing
}
if (flags.AnimKit)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
*data << uint16(self->GetAIAnimKitId()); // AiID
*data << uint16(self->GetMovementAnimKitId()); // MovementID
*data << uint16(self->GetMeleeAnimKitId()); // MeleeID
data << uint16(self->GetAIAnimKitId()); // AiID
data << uint16(self->GetMovementAnimKitId()); // MovementID
data << uint16(self->GetMeleeAnimKitId()); // MeleeID
}
if (flags.Rotation)
{
GameObject const* gameObject = static_cast<GameObject const*>(this);
*data << uint64(gameObject->GetPackedLocalRotation()); // Rotation
data << uint64(gameObject->GetPackedLocalRotation()); // Rotation
}
//if (flags.Room)
// *data << ObjectGuid(HouseGUID);
// data << ObjectGuid(HouseGUID);
//if (flags.Decor)
// *data << ObjectGuid(RoomGUID);
// data << ObjectGuid(RoomGUID);
//if (flags.MeshObject)
//{
// *data << ObjectGuid(AttachParentGUID);
// *data << TaggedPosition<Position::XYZ>(PositionLocalSpace);
// *data << QuaternionData(RotationLocalSpace);
// *data << float(ScaleLocalSpace);
// *data << uint8(AttachmentFlags);
// data << ObjectGuid(AttachParentGUID);
// data << TaggedPosition<Position::XYZ>(PositionLocalSpace);
// data << QuaternionData(RotationLocalSpace);
// data << float(ScaleLocalSpace);
// data << uint8(AttachmentFlags);
//}
if (!PauseTimes.empty())
data->append(PauseTimes.data(), PauseTimes.size());
data.append(PauseTimes.data(), PauseTimes.size());
if (flags.MovementTransport)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
*data << self->m_movementInfo.transport;
data << self->m_movementInfo.transport;
}
if (flags.GameObject)
@@ -441,30 +467,30 @@ void BaseEntity::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, P
bool bit8 = false;
bool isTransport = gameObject->GetGOInfo()->type == GAMEOBJECT_TYPE_MAP_OBJ_TRANSPORT;
*data << uint32(gameObject->GetWorldEffectID());
data << uint32(gameObject->GetWorldEffectID());
data->WriteBit(bit8);
data->WriteBit(isTransport);
data->WriteBit(gameObject->GetPathProgressForClient().has_value());
data->FlushBits();
data.WriteBit(bit8);
data.WriteBit(isTransport);
data.WriteBit(gameObject->GetPathProgressForClient().has_value());
data.FlushBits();
if (isTransport)
{
Transport const* transport = static_cast<Transport const*>(gameObject);
uint32 period = transport->GetTransportPeriod();
*data << uint32((((int64(transport->GetTimer()) - int64(GameTime::GetGameTimeMS())) % period) + period) % period); // TimeOffset
*data << uint32(transport->GetNextStopTimestamp().value_or(0));
data->WriteBit(transport->GetNextStopTimestamp().has_value());
data->WriteBit(transport->IsStopped());
data->WriteBit(false);
data->FlushBits();
data << uint32((((int64(transport->GetTimer()) - int64(GameTime::GetGameTimeMS())) % period) + period) % period); // TimeOffset
data << uint32(transport->GetNextStopTimestamp().value_or(0));
data.WriteBit(transport->GetNextStopTimestamp().has_value());
data.WriteBit(transport->IsStopped());
data.WriteBit(false);
data.FlushBits();
}
if (bit8)
*data << uint32(0);
data << uint32(0);
if (gameObject->GetPathProgressForClient())
*data << float(*gameObject->GetPathProgressForClient());
data << float(*gameObject->GetPathProgressForClient());
}
if (flags.SmoothPhasing)
@@ -472,121 +498,121 @@ void BaseEntity::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, P
SmoothPhasingInfo const* smoothPhasingInfo = static_cast<WorldObject const*>(this)->GetSmoothPhasing()->GetInfoForSeer(target->GetGUID());
ASSERT(smoothPhasingInfo);
data->WriteBit(smoothPhasingInfo->ReplaceActive);
data->WriteBit(smoothPhasingInfo->StopAnimKits);
data->WriteBit(smoothPhasingInfo->ReplaceObject.has_value());
data->FlushBits();
data.WriteBit(smoothPhasingInfo->ReplaceActive);
data.WriteBit(smoothPhasingInfo->StopAnimKits);
data.WriteBit(smoothPhasingInfo->ReplaceObject.has_value());
data.FlushBits();
if (smoothPhasingInfo->ReplaceObject)
*data << *smoothPhasingInfo->ReplaceObject;
data << *smoothPhasingInfo->ReplaceObject;
}
if (flags.SceneObject)
{
data->WriteBit(false); // HasLocalScriptData
data->WriteBit(false); // HasPetBattleFullUpdate
data->FlushBits();
data.WriteBit(false); // HasLocalScriptData
data.WriteBit(false); // HasPetBattleFullUpdate
data.FlushBits();
// if (HasLocalScriptData)
// {
// data->WriteBits(Data.length(), 7);
// data->FlushBits();
// data->WriteString(Data);
// data.WriteBits(Data.length(), 7);
// data.FlushBits();
// data.WriteString(Data);
// }
// if (HasPetBattleFullUpdate)
// {
// for (std::size_t i = 0; i < 2; ++i)
// {
// *data << ObjectGuid(Players[i].CharacterID);
// *data << int32(Players[i].TrapAbilityID);
// *data << int32(Players[i].TrapStatus);
// *data << uint16(Players[i].RoundTimeSecs);
// *data << int8(Players[i].FrontPet);
// *data << uint8(Players[i].InputFlags);
// data << ObjectGuid(Players[i].CharacterID);
// data << int32(Players[i].TrapAbilityID);
// data << int32(Players[i].TrapStatus);
// data << uint16(Players[i].RoundTimeSecs);
// data << int8(Players[i].FrontPet);
// data << uint8(Players[i].InputFlags);
// data->WriteBits(Players[i].Pets.size(), 2);
// data->FlushBits();
// data.WriteBits(Players[i].Pets.size(), 2);
// data.FlushBits();
// for (std::size_t j = 0; j < Players[i].Pets.size(); ++j)
// {
// *data << ObjectGuid(Players[i].Pets[j].BattlePetGUID);
// *data << int32(Players[i].Pets[j].SpeciesID);
// *data << int32(Players[i].Pets[j].CreatureID);
// *data << int32(Players[i].Pets[j].DisplayID);
// *data << int16(Players[i].Pets[j].Level);
// *data << int16(Players[i].Pets[j].Xp);
// *data << int32(Players[i].Pets[j].CurHealth);
// *data << int32(Players[i].Pets[j].MaxHealth);
// *data << int32(Players[i].Pets[j].Power);
// *data << int32(Players[i].Pets[j].Speed);
// *data << int32(Players[i].Pets[j].NpcTeamMemberID);
// *data << uint8(Players[i].Pets[j].BreedQuality);
// *data << uint16(Players[i].Pets[j].StatusFlags);
// *data << int8(Players[i].Pets[j].Slot);
// data << ObjectGuid(Players[i].Pets[j].BattlePetGUID);
// data << int32(Players[i].Pets[j].SpeciesID);
// data << int32(Players[i].Pets[j].CreatureID);
// data << int32(Players[i].Pets[j].DisplayID);
// data << int16(Players[i].Pets[j].Level);
// data << int16(Players[i].Pets[j].Xp);
// data << int32(Players[i].Pets[j].CurHealth);
// data << int32(Players[i].Pets[j].MaxHealth);
// data << int32(Players[i].Pets[j].Power);
// data << int32(Players[i].Pets[j].Speed);
// data << int32(Players[i].Pets[j].NpcTeamMemberID);
// data << uint8(Players[i].Pets[j].BreedQuality);
// data << uint16(Players[i].Pets[j].StatusFlags);
// data << int8(Players[i].Pets[j].Slot);
// *data << uint32(Players[i].Pets[j].Abilities.size());
// *data << uint32(Players[i].Pets[j].Auras.size());
// *data << uint32(Players[i].Pets[j].States.size());
// data << uint32(Players[i].Pets[j].Abilities.size());
// data << uint32(Players[i].Pets[j].Auras.size());
// data << uint32(Players[i].Pets[j].States.size());
// for (std::size_t k = 0; k < Players[i].Pets[j].Abilities.size(); ++k)
// {
// *data << int32(Players[i].Pets[j].Abilities[k].AbilityID);
// *data << int16(Players[i].Pets[j].Abilities[k].CooldownRemaining);
// *data << int16(Players[i].Pets[j].Abilities[k].LockdownRemaining);
// *data << int8(Players[i].Pets[j].Abilities[k].AbilityIndex);
// *data << uint8(Players[i].Pets[j].Abilities[k].Pboid);
// data << int32(Players[i].Pets[j].Abilities[k].AbilityID);
// data << int16(Players[i].Pets[j].Abilities[k].CooldownRemaining);
// data << int16(Players[i].Pets[j].Abilities[k].LockdownRemaining);
// data << int8(Players[i].Pets[j].Abilities[k].AbilityIndex);
// data << uint8(Players[i].Pets[j].Abilities[k].Pboid);
// }
// for (std::size_t k = 0; k < Players[i].Pets[j].Auras.size(); ++k)
// {
// *data << int32(Players[i].Pets[j].Auras[k].AbilityID);
// *data << uint32(Players[i].Pets[j].Auras[k].InstanceID);
// *data << int32(Players[i].Pets[j].Auras[k].RoundsRemaining);
// *data << int32(Players[i].Pets[j].Auras[k].CurrentRound);
// *data << uint8(Players[i].Pets[j].Auras[k].CasterPBOID);
// data << int32(Players[i].Pets[j].Auras[k].AbilityID);
// data << uint32(Players[i].Pets[j].Auras[k].InstanceID);
// data << int32(Players[i].Pets[j].Auras[k].RoundsRemaining);
// data << int32(Players[i].Pets[j].Auras[k].CurrentRound);
// data << uint8(Players[i].Pets[j].Auras[k].CasterPBOID);
// }
// for (std::size_t k = 0; k < Players[i].Pets[j].States.size(); ++k)
// {
// *data << uint32(Players[i].Pets[j].States[k].StateID);
// *data << int32(Players[i].Pets[j].States[k].StateValue);
// data << uint32(Players[i].Pets[j].States[k].StateID);
// data << int32(Players[i].Pets[j].States[k].StateValue);
// }
// data->WriteBits(Players[i].Pets[j].CustomName.length(), 7);
// data->FlushBits();
// data->WriteString(Players[i].Pets[j].CustomName);
// data.WriteBits(Players[i].Pets[j].CustomName.length(), 7);
// data.FlushBits();
// data.WriteString(Players[i].Pets[j].CustomName);
// }
// }
// for (std::size_t i = 0; i < 3; ++i)
// {
// *data << uint32(Enviros[j].Auras.size());
// *data << uint32(Enviros[j].States.size());
// data << uint32(Enviros[j].Auras.size());
// data << uint32(Enviros[j].States.size());
// for (std::size_t j = 0; j < Enviros[j].Auras.size(); ++j)
// {
// *data << int32(Enviros[j].Auras[j].AbilityID);
// *data << uint32(Enviros[j].Auras[j].InstanceID);
// *data << int32(Enviros[j].Auras[j].RoundsRemaining);
// *data << int32(Enviros[j].Auras[j].CurrentRound);
// *data << uint8(Enviros[j].Auras[j].CasterPBOID);
// data << int32(Enviros[j].Auras[j].AbilityID);
// data << uint32(Enviros[j].Auras[j].InstanceID);
// data << int32(Enviros[j].Auras[j].RoundsRemaining);
// data << int32(Enviros[j].Auras[j].CurrentRound);
// data << uint8(Enviros[j].Auras[j].CasterPBOID);
// }
// for (std::size_t j = 0; j < Enviros[j].States.size(); ++j)
// {
// *data << uint32(Enviros[i].States[j].StateID);
// *data << int32(Enviros[i].States[j].StateValue);
// data << uint32(Enviros[i].States[j].StateID);
// data << int32(Enviros[i].States[j].StateValue);
// }
// }
// *data << uint16(WaitingForFrontPetsMaxSecs);
// *data << uint16(PvpMaxRoundTime);
// *data << int32(CurRound);
// *data << uint32(NpcCreatureID);
// *data << uint32(NpcDisplayID);
// *data << int8(CurPetBattleState);
// *data << uint8(ForfeitPenalty);
// *data << ObjectGuid(InitialWildPetGUID);
// data->WriteBit(IsPVP);
// data->WriteBit(CanAwardXP);
// data->FlushBits();
// data << uint16(WaitingForFrontPetsMaxSecs);
// data << uint16(PvpMaxRoundTime);
// data << int32(CurRound);
// data << uint32(NpcCreatureID);
// data << uint32(NpcDisplayID);
// data << int8(CurPetBattleState);
// data << uint8(ForfeitPenalty);
// data << ObjectGuid(InitialWildPetGUID);
// data.WriteBit(IsPVP);
// data.WriteBit(CanAwardXP);
// data.FlushBits();
// }
}
@@ -597,35 +623,35 @@ void BaseEntity::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, P
bool HasSceneInstanceIDs = !player->GetSceneMgr().GetSceneTemplateByInstanceMap().empty();
bool HasRuneState = player->GetPowerIndex(POWER_RUNES) != MAX_POWERS;
data->WriteBit(HasSceneInstanceIDs);
data->WriteBit(HasRuneState);
data->FlushBits();
data.WriteBit(HasSceneInstanceIDs);
data.WriteBit(HasRuneState);
data.FlushBits();
if (HasSceneInstanceIDs)
{
*data << uint32(player->GetSceneMgr().GetSceneTemplateByInstanceMap().size());
data << uint32(player->GetSceneMgr().GetSceneTemplateByInstanceMap().size());
for (auto const& [sceneInstanceId, _] : player->GetSceneMgr().GetSceneTemplateByInstanceMap())
*data << uint32(sceneInstanceId);
data << uint32(sceneInstanceId);
}
if (HasRuneState)
{
float baseCd = float(player->GetRuneBaseCooldown());
uint32 maxRunes = uint32(player->GetMaxPower(POWER_RUNES));
*data << uint8((1 << maxRunes) - 1);
*data << uint8(player->GetRunesState());
*data << uint32(maxRunes);
data << uint8((1 << maxRunes) - 1);
data << uint8(player->GetRunesState());
data << uint32(maxRunes);
for (uint32 i = 0; i < maxRunes; ++i)
*data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255);
data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255);
}
}
if (flags.Conversation)
{
Conversation const* self = static_cast<Conversation const*>(this);
if (data->WriteBit(self->GetTextureKitId() != 0))
*data << uint32(self->GetTextureKitId());
if (data.WriteBit(self->GetTextureKitId() != 0))
data << uint32(self->GetTextureKitId());
data->FlushBits();
data.FlushBits();
}
}
@@ -642,6 +668,9 @@ void BaseEntity::AddToObjectUpdateIfNeeded()
void BaseEntity::ClearUpdateMask(bool remove)
{
for (std::size_t i = 0; i < m_entityFragments.UpdateableCount; ++i)
WowCS::EntityFragmentInfo->ClearChanged[static_cast<std::size_t>(m_entityFragments.Updateable.Ids[i])](m_entityFragments.Updateable.Data[i]);
m_entityFragments.IdsChanged = false;
if (m_objectUpdated)
@@ -656,7 +685,7 @@ void BaseEntity::BuildUpdateChangesMask()
{
for (std::size_t i = 0; i < m_entityFragments.UpdateableCount; ++i)
{
if (m_entityFragments.Updateable.IsChanged[i](this))
if (WowCS::EntityFragmentInfo->IsChanged[static_cast<std::size_t>(m_entityFragments.Updateable.Ids[i])](m_entityFragments.Updateable.Data[i]))
m_entityFragments.ContentsChangedMask |= m_entityFragments.Updateable.Masks[i];
else
m_entityFragments.ContentsChangedMask &= ~m_entityFragments.Updateable.Masks[i];

View File

@@ -78,9 +78,6 @@ namespace UF
template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
inline void ClearChangesMask(UpdateField<T, BlockBit, Bit>(Derived::* field));
template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
inline void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>(Derived::* field));
uint32 GetChangedObjectTypeMask() const { return _changesMask; }
bool HasChanged(uint32 index) const { return (_changesMask & UpdateMaskHelpers::GetBlockFlag(index)) != 0; }
@@ -193,7 +190,7 @@ class TC_GAME_API BaseEntity
virtual void DestroyForPlayer(Player const* target) const;
void SendOutOfRangeForPlayer(Player const* target) const;
virtual void ClearUpdateMask(bool remove);
void ClearUpdateMask(bool remove);
virtual std::string GetNameForLocaleIdx(LocaleConstant locale) const = 0;
@@ -347,9 +344,9 @@ class TC_GAME_API BaseEntity
}
}
void BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Player const* target) const;
void BuildMovementUpdate(ByteBuffer& data, CreateObjectBits flags, Player const* target) const;
virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const;
static void BuildEntityFragments(ByteBuffer* data, std::span<WowCS::EntityFragment const> fragments);
static void BuildEntityFragments(ByteBuffer& data, std::span<WowCS::EntityFragment const> fragments);
TypeID m_objectTypeId = NUM_CLIENT_OBJECT_TYPES;
CreateObjectBits m_updateFlag = {};
@@ -423,23 +420,12 @@ inline UF::MutableFieldReference<T, false> UF::UpdateFieldHolder::ModifyValue(Op
template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
inline void UF::UpdateFieldHolder::ClearChangesMask(UpdateField<T, BlockBit, Bit> Derived::* field)
{
static_assert(WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject);
BaseEntity* owner = GetOwner();
if constexpr (WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject)
_changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit);
_changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit);
(static_cast<Derived*>(owner)->*field)._value.ClearChangesMask();
}
template <typename Derived, typename T, int32 BlockBit, uint32 Bit>
inline void UF::UpdateFieldHolder::ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit> Derived::* field)
{
BaseEntity* owner = GetOwner();
if constexpr (WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject)
_changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit);
auto& uf = (static_cast<Derived*>(owner)->*field);
if (uf.has_value())
uf._value->ClearChangesMask();
}
#endif // TRINITYCORE_BASE_ENTITY_H

View File

@@ -61,12 +61,21 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max
MAX_VISIBILITY_DISTANCE
};
struct Object::ObjectFragmentInfoInitializer
{
ObjectFragmentInfoInitializer()
{
WowCS::EntityFragmentInfos::Register(WowCS::EntityFragment::CGObject,
&Object::BuildObjectFragmentCreate, &Object::BuildObjectFragmentUpdate,
&Object::IsObjectFragmentChanged, &Object::ClearObjectFragmentChanged);
}
} static InitObjectFragment;
Object::Object() : m_scriptRef(this, NoopObjectDeleter())
{
m_objectTypeId = TYPEID_OBJECT;
m_entityFragments.Add(WowCS::EntityFragment::CGObject, false,
&Object::BuildObjectFragmentCreate, &Object::BuildObjectFragmentUpdate, &Object::IsObjectFragmentChanged);
m_entityFragments.Add(WowCS::EntityFragment::CGObject, false, this);
}
Object::~Object() = default;
@@ -94,14 +103,14 @@ void Object::BuildValuesUpdateBlockForPlayerWithFlag(UpdateData* data, UF::Updat
std::size_t sizePos = buf.wpos();
buf << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buf, flags);
BuildValuesUpdateWithFlag(&buf, flags, target);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buf, flags);
BuildValuesUpdateWithFlag(flags, buf, target);
buf.put<uint32>(sizePos, buf.wpos() - sizePos - 4);
data->AddUpdateBlock();
}
void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag<UF::UpdateFieldFlag> flags) const
void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer& data, EnumFlag<UF::UpdateFieldFlag> flags) const
{
uint8 contentsChangedMask = 0;
for (std::size_t i = 0; i < m_entityFragments.UpdateableCount; ++i)
@@ -113,35 +122,39 @@ void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* da
contentsChangedMask |= m_entityFragments.Updateable.Masks[i];
}
*data << uint8(flags.HasFlag(UF::UpdateFieldFlag::Owner));
*data << uint8(false); // m_entityFragments.IdsChanged
*data << uint8(contentsChangedMask);
data << uint8(flags.HasFlag(UF::UpdateFieldFlag::Owner));
data << uint8(false); // m_entityFragments.IdsChanged
data << uint8(contentsChangedMask);
}
void Object::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag /*flags*/, Player const* /*target*/) const
{
*data << uint32(0);
}
void Object::ClearUpdateMask(bool remove)
void Object::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Object::m_objectData);
BaseEntity::ClearUpdateMask(remove);
}
void Object::BuildObjectFragmentCreate(BaseEntity const* entity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target)
void Object::BuildValuesUpdateWithFlag(UF::UpdateFieldFlag /*flags*/, ByteBuffer& data, Player const* /*target*/) const
{
static_cast<Object const*>(entity)->BuildValuesCreate(&data, flags, target);
data << uint32(0);
}
void Object::BuildObjectFragmentUpdate(BaseEntity const* entity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target)
void Object::BuildObjectFragmentCreate(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* /*entity*/)
{
static_cast<Object const*>(entity)->BuildValuesUpdate(&data, flags, target);
static_cast<Object const*>(rawFragmentData)->BuildValuesCreate(flags, data, target);
}
bool Object::IsObjectFragmentChanged(BaseEntity const* entity)
void Object::BuildObjectFragmentUpdate(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* /*entity*/)
{
return entity->m_values.GetChangedObjectTypeMask() != 0;
static_cast<Object const*>(rawFragmentData)->BuildValuesUpdate(flags, data, target);
}
bool Object::IsObjectFragmentChanged(void const* rawFragmentData)
{
return static_cast<Object const*>(rawFragmentData)->m_values.GetChangedObjectTypeMask() != 0;
}
void Object::ClearObjectFragmentChanged(void const* rawFragmentData)
{
const_cast<Object*>(static_cast<Object const*>(rawFragmentData))->ClearValuesChangesMask();
}
std::string Object::GetDebugInfo() const

View File

@@ -100,8 +100,6 @@ class TC_GAME_API Object : public BaseEntity
void BuildValuesUpdateBlockForPlayerWithFlag(UpdateData* data, UF::UpdateFieldFlag flags, Player const* target) const;
void ClearUpdateMask(bool remove) override;
virtual bool hasQuest(uint32 /* quest_id */) const { return false; }
virtual bool hasInvolvedQuest(uint32 /* quest_id */) const { return false; }
@@ -173,17 +171,21 @@ class TC_GAME_API Object : public BaseEntity
protected:
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;
void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag<UF::UpdateFieldFlag> flags) const;
virtual void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const = 0;
virtual void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const = 0;
void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer& data, EnumFlag<UF::UpdateFieldFlag> flags) const;
virtual void ClearValuesChangesMask();
public:
virtual void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const;
virtual void BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const;
private:
static void BuildObjectFragmentCreate(BaseEntity const* entity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target);
static void BuildObjectFragmentUpdate(BaseEntity const* entity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target);
static bool IsObjectFragmentChanged(BaseEntity const* entity);
struct ObjectFragmentInfoInitializer;
friend ObjectFragmentInfoInitializer;
static void BuildObjectFragmentCreate(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* entity);
static void BuildObjectFragmentUpdate(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* entity);
static bool IsObjectFragmentChanged(void const* rawFragmentData);
static void ClearObjectFragmentChanged(void const* rawFragmentData);
struct NoopObjectDeleter { void operator()(Object*) const { /*noop - not managed*/ } };
Trinity::unique_trackable_ptr<Object> m_scriptRef;

View File

@@ -1318,8 +1318,6 @@ namespace UF
template<std::size_t Bits>
friend class HasChangesMask;
friend class UpdateFieldHolder;
public:
template<typename T>
bool Is() const { return std::holds_alternative<T>(_value); }

View File

@@ -70,29 +70,29 @@ inline void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& da
}
template <typename K, typename V, typename T>
inline void WriteMapFieldCreate(MapUpdateFieldBase<K, V> const& map, ByteBuffer& data, T const* owner, Player const* receiver)
inline void WriteMapFieldCreate(MapUpdateFieldBase<K, V> const& map, ByteBuffer& data, Player const* receiver, T const* owner)
{
data << uint32(map.size());
for (auto const& [k, v] : map)
{
if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, K>)
k.WriteCreate(data, owner, receiver);
k.WriteCreate(data, receiver, owner);
else
data << k;
if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, V>)
v.value.WriteCreate(data, owner, receiver);
v.value.WriteCreate(data, receiver, owner);
else
data << v.value;
}
}
template <typename K, typename V, typename T>
inline void WriteMapFieldUpdate(MapUpdateFieldBase<K, V> const& map, ByteBuffer& data, bool ignoreChangesMask, T const* owner, Player const* receiver)
inline void WriteMapFieldUpdate(MapUpdateFieldBase<K, V> const& map, bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, T const* owner)
{
data << uint8(ignoreChangesMask ? 1 : 0);
if (ignoreChangesMask)
UF::WriteMapFieldCreate(map, data, owner, receiver);
UF::WriteMapFieldCreate(map, data, receiver, owner);
else
{
uint16 changesCount = 0;
@@ -107,7 +107,7 @@ inline void WriteMapFieldUpdate(MapUpdateFieldBase<K, V> const& map, ByteBuffer&
++changesCount;
if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, K>)
k.WriteUpdate(data, false, owner, receiver);
k.WriteUpdate(false, data, receiver, owner);
else
data << k;
@@ -116,7 +116,7 @@ inline void WriteMapFieldUpdate(MapUpdateFieldBase<K, V> const& map, ByteBuffer&
continue;
if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, V>)
v.value.WriteUpdate(data, false, owner, receiver);
v.value.WriteUpdate(false, data, receiver, owner);
else
data << v.value;
}
@@ -126,20 +126,20 @@ inline void WriteMapFieldUpdate(MapUpdateFieldBase<K, V> const& map, ByteBuffer&
}
template <typename T, typename O>
inline void WriteSetFieldCreate(SetUpdateFieldBase<T> const& set, ByteBuffer& data, O const* owner, Player const* receiver)
inline void WriteSetFieldCreate(SetUpdateFieldBase<T> const& set, ByteBuffer& data, Player const* receiver, O const* owner)
{
data << uint32(set.size());
for (auto const& [k, _] : set)
{
if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, T>)
k.WriteCreate(data, owner, receiver);
k.WriteCreate(data, receiver, owner);
else
data << k;
}
}
template <typename T, typename O>
inline void WriteSetFieldUpdate(SetUpdateFieldBase<T> const& set, ByteBuffer& data, bool ignoreChangesMask, O const* owner, Player const* receiver)
inline void WriteSetFieldUpdate(SetUpdateFieldBase<T> const& set, bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, O const* owner)
{
data << uint8(ignoreChangesMask ? 1 : 0);
if (ignoreChangesMask)
@@ -158,7 +158,7 @@ inline void WriteSetFieldUpdate(SetUpdateFieldBase<T> const& set, ByteBuffer& da
++changesCount;
if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, T>)
k.WriteUpdate(data, false, owner, receiver);
k.WriteUpdate(false, data, receiver, owner);
else
data << k;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -44,7 +44,7 @@ class ViewerDependentValue<UF::ObjectData::EntryIDTag>
public:
using value_type = UF::ObjectData::EntryIDTag::value_type;
static value_type GetValue(UF::ObjectData const* objectData, Object const* object, Player const* receiver)
static value_type GetValue(UF::ObjectData const* objectData, Player const* receiver, Object const* object)
{
value_type entryId = objectData->EntryID;
@@ -63,7 +63,7 @@ class ViewerDependentValue<UF::ObjectData::DynamicFlagsTag>
public:
using value_type = UF::ObjectData::DynamicFlagsTag::value_type;
static value_type GetValue(UF::ObjectData const* objectData, Object const* object, Player const* receiver)
static value_type GetValue(UF::ObjectData const* objectData, Player const* receiver, Object const* object)
{
value_type dynamicFlags = objectData->DynamicFlags;
if (Unit const* unit = object->ToUnit())
@@ -163,7 +163,7 @@ class ViewerDependentValue<UF::UnitData::DisplayIDTag>
public:
using value_type = UF::UnitData::DisplayIDTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type displayId = unitData->DisplayID;
if (unit->IsCreature())
@@ -213,7 +213,7 @@ class ViewerDependentValue<UF::UnitData::StateWorldEffectIDsTag>
public:
using value_type = UF::UnitData::StateWorldEffectIDsTag::value_type const*;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
if (unit->IsCreature())
if (SpawnTrackingStateData const* spawnTrackingStateData = unit->GetSpawnTrackingStateDataForPlayer(receiver))
@@ -229,7 +229,7 @@ class ViewerDependentValue<UF::UnitData::StateSpellVisualIDTag>
public:
using value_type = UF::UnitData::StateSpellVisualIDTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type stateSpellVisual = unitData->StateSpellVisualID;
@@ -247,7 +247,7 @@ class ViewerDependentValue<UF::UnitData::StateAnimIDTag>
public:
using value_type = UF::UnitData::StateAnimIDTag::value_type;
static value_type GetValue(UF::UnitData const* /*unitData*/, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* /*unitData*/, Player const* receiver, Unit const* unit)
{
value_type stateAnimId = sDB2Manager.GetEmptyAnimStateID();
@@ -265,7 +265,7 @@ class ViewerDependentValue<UF::UnitData::StateAnimKitIDTag>
public:
using value_type = UF::UnitData::StateAnimKitIDTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type stateAnimKitId = unitData->StateAnimKitID;
@@ -283,7 +283,7 @@ class ViewerDependentValue<UF::UnitData::StateWorldEffectsQuestObjectiveIDTag>
public:
using value_type = UF::UnitData::StateWorldEffectsQuestObjectiveIDTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type stateWorldEffectsQuestObjectiveId = unitData->StateWorldEffectsQuestObjectiveID;
@@ -319,7 +319,7 @@ class ViewerDependentValue<UF::UnitData::FactionTemplateTag>
public:
using value_type = UF::UnitData::FactionTemplateTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type factionTemplate = unitData->FactionTemplate;
if (unit->IsControlledByPlayer() && receiver != unit && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && unit->IsInRaidWith(receiver))
@@ -341,7 +341,7 @@ class ViewerDependentValue<UF::UnitData::FlagsTag>
public:
using value_type = UF::UnitData::FlagsTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* /*unit*/, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* /*unit*/)
{
value_type flags = unitData->Flags;
// Gamemasters should be always able to interact with units - remove uninteractible flag
@@ -358,7 +358,7 @@ class ViewerDependentValue<UF::UnitData::Flags2Tag>
public:
using value_type = UF::UnitData::Flags2Tag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* /*unit*/, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* /*unit*/)
{
value_type flags = unitData->Flags2;
// Gamemasters should be always able to interact with units - remove uninteractible flag
@@ -375,7 +375,7 @@ class ViewerDependentValue<UF::UnitData::Flags3Tag>
public:
using value_type = UF::UnitData::Flags3Tag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type flags = unitData->Flags3;
if (flags & UNIT_FLAG3_ALREADY_SKINNED && unit->IsCreature() && !unit->ToCreature()->IsSkinnedBy(receiver))
@@ -391,7 +391,7 @@ class ViewerDependentValue<UF::UnitData::Flags4Tag>
public:
using value_type = UF::UnitData::Flags4Tag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* /*unit*/, Player const* /*receiver*/)
static value_type GetValue(UF::UnitData const* unitData, Player const* /*receiver*/, Unit const* /*unit*/)
{
return unitData->Flags4;
}
@@ -403,7 +403,7 @@ class ViewerDependentValue<UF::UnitData::AuraStateTag>
public:
using value_type = UF::UnitData::AuraStateTag::value_type;
static value_type GetValue(UF::UnitData const* /*unitData*/, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* /*unitData*/, Player const* receiver, Unit const* unit)
{
// Check per caster aura states to not enable using a spell in client if specified aura is not by target
return unit->BuildAuraStateUpdateForTarget(receiver);
@@ -416,7 +416,7 @@ class ViewerDependentValue<UF::UnitData::PvpFlagsTag>
public:
using value_type = UF::UnitData::PvpFlagsTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type pvpFlags = unitData->PvpFlags;
if (unit->IsControlledByPlayer() && receiver != unit && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && unit->IsInRaidWith(receiver))
@@ -438,7 +438,7 @@ class ViewerDependentValue<UF::UnitData::InteractSpellIDTag>
public:
using value_type = UF::UnitData::InteractSpellIDTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type interactSpellId = unitData->InteractSpellID;
if (unitData->NpcFlags & UNIT_NPC_FLAG_SPELLCLICK && !interactSpellId)
@@ -468,7 +468,7 @@ class ViewerDependentValue<UF::UnitData::NpcFlagsTag>
public:
using value_type = UF::UnitData::NpcFlagsTag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type npcFlag = unitData->NpcFlags;
if (npcFlag)
@@ -495,7 +495,7 @@ class ViewerDependentValue<UF::UnitData::NpcFlags2Tag>
public:
using value_type = UF::UnitData::NpcFlags2Tag::value_type;
static value_type GetValue(UF::UnitData const* unitData, Unit const* unit, Player const* receiver)
static value_type GetValue(UF::UnitData const* unitData, Player const* receiver, Unit const* unit)
{
value_type npcFlag = unitData->NpcFlags2;
if (npcFlag)
@@ -514,7 +514,7 @@ class ViewerDependentValue<UF::GameObjectData::StateWorldEffectIDsTag>
public:
using value_type = UF::GameObjectData::StateWorldEffectIDsTag::value_type const*;
static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* gameObjectData, Player const* receiver, GameObject const* gameObject)
{
if (SpawnTrackingStateData const* spawnTrackingStateData = gameObject->GetSpawnTrackingStateDataForPlayer(receiver))
return &spawnTrackingStateData->StateWorldEffects;
@@ -529,7 +529,7 @@ class ViewerDependentValue<UF::GameObjectData::StateSpellVisualIDTag>
public:
using value_type = UF::GameObjectData::StateSpellVisualIDTag::value_type;
static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* gameObjectData, Player const* receiver, GameObject const* gameObject)
{
value_type stateSpellVisual = gameObjectData->StateSpellVisualID;
@@ -546,7 +546,7 @@ class ViewerDependentValue<UF::GameObjectData::SpawnTrackingStateAnimIDTag>
public:
using value_type = UF::GameObjectData::SpawnTrackingStateAnimIDTag::value_type;
static value_type GetValue(UF::GameObjectData const* /*gameObjectData*/, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* /*gameObjectData*/, Player const* receiver, GameObject const* gameObject)
{
value_type stateAnimId = sDB2Manager.GetEmptyAnimStateID();
@@ -563,7 +563,7 @@ class ViewerDependentValue<UF::GameObjectData::SpawnTrackingStateAnimKitIDTag>
public:
using value_type = UF::GameObjectData::SpawnTrackingStateAnimKitIDTag::value_type;
static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* gameObjectData, Player const* receiver, GameObject const* gameObject)
{
value_type stateAnimKitId = gameObjectData->SpawnTrackingStateAnimKitID;
@@ -580,7 +580,7 @@ class ViewerDependentValue<UF::GameObjectData::StateWorldEffectsQuestObjectiveID
public:
using value_type = UF::GameObjectData::StateWorldEffectsQuestObjectiveIDTag::value_type;
static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* gameObjectData, Player const* receiver, GameObject const* gameObject)
{
value_type stateWorldEffectsQuestObjectiveId = gameObjectData->StateWorldEffectsQuestObjectiveID;
@@ -616,7 +616,7 @@ class ViewerDependentValue<UF::GameObjectData::FlagsTag>
public:
using value_type = UF::GameObjectData::FlagsTag::value_type;
static value_type GetValue(UF::GameObjectData const* gameObjectData, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* gameObjectData, Player const* receiver, GameObject const* gameObject)
{
value_type flags = gameObjectData->Flags;
if (gameObject->GetGoType() == GAMEOBJECT_TYPE_CHEST)
@@ -633,7 +633,7 @@ class ViewerDependentValue<UF::GameObjectData::StateTag>
public:
using value_type = UF::GameObjectData::StateTag::value_type;
static value_type GetValue(UF::GameObjectData const* /*gameObjectData*/, GameObject const* gameObject, Player const* receiver)
static value_type GetValue(UF::GameObjectData const* /*gameObjectData*/, Player const* receiver, GameObject const* gameObject)
{
return gameObject->GetGoStateFor(receiver->GetGUID());
}
@@ -645,7 +645,7 @@ class ViewerDependentValue<UF::ConversationData::LastLineEndTimeTag>
public:
using value_type = UF::ConversationData::LastLineEndTimeTag::value_type;
static value_type GetValue(UF::ConversationData const* /*conversationData*/, Conversation const* conversation, Player const* receiver)
static value_type GetValue(UF::ConversationData const* /*conversationData*/, Player const* receiver, Conversation const* conversation)
{
LocaleConstant locale = receiver->GetSession()->GetSessionDbLocaleIndex();
return conversation->GetLastLineEndTime(locale).count();
@@ -658,7 +658,7 @@ class ViewerDependentValue<UF::ConversationLine::StartTimeTag>
public:
using value_type = UF::ConversationLine::StartTimeTag::value_type;
static value_type GetValue(UF::ConversationLine const* conversationLineData, Conversation const* conversation, Player const* receiver)
static value_type GetValue(UF::ConversationLine const* conversationLineData, Player const* receiver, Conversation const* conversation)
{
value_type startTime = conversationLineData->StartTime;
LocaleConstant locale = receiver->GetSession()->GetSessionDbLocaleIndex();

View File

@@ -21,8 +21,7 @@
namespace WowCS
{
void EntityFragmentsHolder::Add(EntityFragment fragment, bool update,
EntityFragmentSerializeFn serializeCreate, EntityFragmentSerializeFn serializeUpdate, EntityFragmentIsChangedFn isChanged)
void EntityFragmentsHolder::Add(EntityFragment fragment, bool update, void const* data /*= nullptr*/)
{
ASSERT(Count < Ids.size());
@@ -45,7 +44,7 @@ void EntityFragmentsHolder::Add(EntityFragment fragment, bool update,
if (IsUpdateableFragment(fragment))
{
ASSERT(UpdateableCount < Updateable.Ids.size());
ASSERT(serializeCreate && serializeUpdate && isChanged);
ASSERT(data);
auto insertedItr = insertSorted(Updateable.Ids, UpdateableCount, fragment).first;
std::ptrdiff_t index = std::ranges::distance(Updateable.Ids.begin(), insertedItr);
@@ -69,9 +68,7 @@ void EntityFragmentsHolder::Add(EntityFragment fragment, bool update,
arr[i] = value;
};
insertAtIndex(Updateable.SerializeCreate, UpdateableCount, index, serializeCreate);
insertAtIndex(Updateable.SerializeUpdate, UpdateableCount, index, serializeUpdate);
insertAtIndex(Updateable.IsChanged, UpdateableCount, index, isChanged);
insertAtIndex(Updateable.Data, UpdateableCount, index, data);
}
if (update)
@@ -121,12 +118,29 @@ void EntityFragmentsHolder::Remove(EntityFragment fragment)
};
uint8 oldSize = UpdateableCount + 1;
removeAtIndex(Updateable.SerializeCreate, oldSize, index, nullptr);
removeAtIndex(Updateable.SerializeUpdate, oldSize, index, nullptr);
removeAtIndex(Updateable.IsChanged, oldSize, index, nullptr);
removeAtIndex(Updateable.Data, oldSize, index, nullptr);
}
}
IdsChanged = true;
}
EntityFragmentInfos const* EntityFragmentInfo;
void EntityFragmentInfos::Register(EntityFragment fragment, EntityFragmentSerializeFn serializeCreate,
EntityFragmentSerializeFn serializeUpdate, EntityFragmentIsChangedFn isChanged, EntityFragmentClearChangedFn clearChanged)
{
static EntityFragmentInfos entityFragmentInfo;
std::size_t index = static_cast<std::size_t>(fragment);
entityFragmentInfo.SerializeCreate[index] = serializeCreate;
entityFragmentInfo.SerializeUpdate[index] = serializeUpdate;
entityFragmentInfo.IsChanged[index] = isChanged;
entityFragmentInfo.ClearChanged[index] = clearChanged;
}
EntityFragmentInfos::EntityFragmentInfos()
{
EntityFragmentInfo = this;
}
}

View File

@@ -111,36 +111,6 @@ inline constexpr bool IsIndirectFragment(EntityFragment frag)
|| frag == EntityFragment::PlayerInitiativeComponent_C;
}
template <auto /*FragmentMemberPtr*/>
struct FragmentSerializationTraits
{
};
template <typename Entity, typename Fragment, Fragment Entity::* FragmentData>
struct FragmentSerializationTraits<FragmentData>
{
static void BuildCreate(BaseEntity const* baseEntity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target)
{
Entity const* entity = static_cast<Entity const*>(baseEntity);
(entity->*FragmentData)->WriteCreate(data, flags, entity, target);
}
static void BuildUpdate(BaseEntity const* baseEntity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target)
{
Entity const* entity = static_cast<Entity const*>(baseEntity);
(entity->*FragmentData)->WriteUpdate(data, flags, entity, target);
}
static bool IsChanged(BaseEntity const* baseEntity)
{
Entity const* entity = static_cast<Entity const*>(baseEntity);
return (entity->*FragmentData)->GetChangesMask().IsAnySet();
}
};
using EntityFragmentSerializeFn = void (*)(BaseEntity const* entity, ByteBuffer& data, UF::UpdateFieldFlag flags, Player const* target);
using EntityFragmentIsChangedFn = bool (*)(BaseEntity const* entity);
struct EntityFragmentsHolder
{
std::array<EntityFragment, 8> Ids =
@@ -158,9 +128,7 @@ struct EntityFragmentsHolder
EntityFragment::End, EntityFragment::End, EntityFragment::End, EntityFragment::End
};
std::array<uint8, N> Masks = { };
std::array<EntityFragmentSerializeFn, N> SerializeCreate = { };
std::array<EntityFragmentSerializeFn, N> SerializeUpdate = { };
std::array<EntityFragmentIsChangedFn, N> IsChanged = { };
std::array<void const*, N> Data;
};
UpdateableFragments Updateable;
@@ -171,16 +139,7 @@ struct EntityFragmentsHolder
uint8 UpdateableCount = 0;
uint8 ContentsChangedMask = 0;
void Add(EntityFragment fragment, bool update,
EntityFragmentSerializeFn serializeCreate, EntityFragmentSerializeFn serializeUpdate, EntityFragmentIsChangedFn isChanged);
inline void Add(EntityFragment fragment, bool update) { Add(fragment, update, nullptr, nullptr, nullptr); }
template <typename SerializationTraits>
inline void Add(EntityFragment fragment, bool update, SerializationTraits)
{
Add(fragment, update, &SerializationTraits::BuildCreate, &SerializationTraits::BuildUpdate, &SerializationTraits::IsChanged);
}
void Add(EntityFragment fragment, bool update, void const* data = nullptr);
void Remove(EntityFragment fragment);
@@ -192,6 +151,66 @@ enum class EntityFragmentSerializationType : uint8
Full = 0,
Partial = 1
};
template <typename T>
inline void const* GetRawFragmentData(T const& fragmentData)
{
return std::addressof(*fragmentData);
}
template <typename FragmentData>
struct FragmentSerializationTraits
{
static void BuildCreate(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* baseEntity)
{
static_cast<FragmentData const*>(rawFragmentData)->WriteCreate(flags, data, target, reinterpret_cast<FragmentData::OwnerObject const*>(baseEntity));
}
static void BuildUpdate(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* baseEntity)
{
static_cast<FragmentData const*>(rawFragmentData)->WriteUpdate(flags, data, target, reinterpret_cast<FragmentData::OwnerObject const*>(baseEntity));
}
static bool IsChanged(void const* rawFragmentData)
{
return static_cast<FragmentData const*>(rawFragmentData)->GetChangesMask().IsAnySet();
}
static void ClearChanged(void const* rawFragmentData)
{
const_cast<FragmentData*>(static_cast<FragmentData const*>(rawFragmentData))->ClearChangesMask();
}
};
using EntityFragmentSerializeFn = void (*)(void const* rawFragmentData, UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target, BaseEntity const* baseEntity);
using EntityFragmentIsChangedFn = bool (*)(void const* rawFragmentData);
using EntityFragmentClearChangedFn = void (*)(void const* rawFragmentData);
struct EntityFragmentInfos
{
static constexpr std::size_t N = static_cast<std::size_t>(EntityFragment::End) + 1;
std::array<EntityFragmentSerializeFn, N> SerializeCreate = { };
std::array<EntityFragmentSerializeFn, N> SerializeUpdate = { };
std::array<EntityFragmentIsChangedFn, N> IsChanged = { };
std::array<EntityFragmentClearChangedFn, N> ClearChanged = { };
static void Register(EntityFragment fragment,
EntityFragmentSerializeFn serializeCreate, EntityFragmentSerializeFn serializeUpdate,
EntityFragmentIsChangedFn isChanged, EntityFragmentClearChangedFn clearChanged);
template <typename SerializationTraits>
inline static void Register(EntityFragment fragment, SerializationTraits)
{
EntityFragmentInfos::Register(fragment, &SerializationTraits::BuildCreate, &SerializationTraits::BuildUpdate,
&SerializationTraits::IsChanged, &SerializationTraits::ClearChanged);
}
private:
EntityFragmentInfos();
};
extern EntityFragmentInfos const* EntityFragmentInfo;
}
#endif // TRINITYCORE_WOWCS_ENTITY_DEFINITIONS_H

View File

@@ -3613,47 +3613,47 @@ UF::UpdateFieldFlag Player::GetUpdateFieldFlagsFor(Player const* target) const
return flags;
}
void Player::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Player::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_unitData->WriteCreate(*data, flags, this, target);
m_playerData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_unitData->WriteCreate(flags, data, target, this);
m_playerData->WriteCreate(flags, data, target, this);
if (target == this)
m_activePlayerData->WriteCreate(*data, flags, this, target);
m_activePlayerData->WriteCreate(flags, data, target, this);
}
void Player::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Player::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask() & ~(uint32(target != this) << TYPEID_ACTIVE_PLAYER));
data << uint32(m_values.GetChangedObjectTypeMask() & ~(uint32(target != this) << TYPEID_ACTIVE_PLAYER));
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_UNIT))
m_unitData->WriteUpdate(*data, flags, this, target);
m_unitData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_PLAYER))
m_playerData->WriteUpdate(*data, flags, this, target);
m_playerData->WriteUpdate(flags, data, target, this);
if (target == this && m_values.HasChanged(TYPEID_ACTIVE_PLAYER))
m_activePlayerData->WriteUpdate(*data, flags, this, target);
m_activePlayerData->WriteUpdate(flags, data, target, this);
}
void Player::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void Player::BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask;
valuesMask.Set(TYPEID_UNIT);
valuesMask.Set(TYPEID_PLAYER);
*data << uint32(valuesMask.GetBlock(0));
data << uint32(valuesMask.GetBlock(0));
UF::UnitData::Mask mask;
m_unitData->AppendAllowedFieldsMaskForFlag(mask, flags);
m_unitData->WriteUpdate(*data, mask, true, this, target);
UF::UnitData::AppendAllowedFieldsMaskForFlag(mask, flags);
m_unitData->WriteUpdate(mask, data, target, this, true);
UF::PlayerData::Mask mask2;
m_playerData->AppendAllowedFieldsMaskForFlag(mask2, flags);
m_playerData->WriteUpdate(*data, mask2, true, this, target);
UF::PlayerData::AppendAllowedFieldsMaskForFlag(mask2, flags);
m_playerData->WriteUpdate(mask2, data, target, this, true);
}
void Player::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -3666,12 +3666,12 @@ void Player::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData
valuesMask.Set(TYPEID_OBJECT);
UF::UnitData::Mask unitMask = requestedUnitMask;
m_unitData->FilterDisallowedFieldsMaskForFlag(unitMask, flags);
UF::UnitData::FilterDisallowedFieldsMaskForFlag(unitMask, flags);
if (unitMask.IsAnySet())
valuesMask.Set(TYPEID_UNIT);
UF::PlayerData::Mask playerMask = requestedPlayerMask;
m_playerData->FilterDisallowedFieldsMaskForFlag(playerMask, flags);
UF::PlayerData::FilterDisallowedFieldsMaskForFlag(playerMask, flags);
if (playerMask.IsAnySet())
valuesMask.Set(TYPEID_PLAYER);
@@ -3681,20 +3681,20 @@ void Player::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_UNIT])
m_unitData->WriteUpdate(buffer, unitMask, true, this, target);
m_unitData->WriteUpdate(unitMask, buffer, target, this, true);
if (valuesMask[TYPEID_PLAYER])
m_playerData->WriteUpdate(buffer, playerMask, true, this, target);
m_playerData->WriteUpdate(playerMask, buffer, target, this, true);
if (valuesMask[TYPEID_ACTIVE_PLAYER])
m_activePlayerData->WriteUpdate(buffer, requestedActivePlayerMask, true, this, target);
m_activePlayerData->WriteUpdate(requestedActivePlayerMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -3725,11 +3725,11 @@ void Player::DestroyForPlayer(Player const* target) const
}
}
void Player::ClearUpdateMask(bool remove)
void Player::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Player::m_playerData);
m_values.ClearChangesMask(&Player::m_activePlayerData);
Unit::ClearUpdateMask(remove);
Unit::ClearValuesChangesMask();
}
bool Player::HasSpell(uint32 spell) const

View File

@@ -2210,13 +2210,13 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
protected:
UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const override;
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override;
void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdateWithFlag(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::UnitData::Mask const& requestedUnitMask,
UF::PlayerData::Mask const& requestedPlayerMask, UF::ActivePlayerData::Mask const& requestedActivePlayerMask, Player const* target) const;

View File

@@ -137,21 +137,21 @@ bool SceneObject::Create(ObjectGuid::LowType lowGuid, SceneType type, uint32 sce
return true;
}
void SceneObject::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void SceneObject::BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
m_objectData->WriteCreate(*data, flags, this, target);
m_sceneObjectData->WriteCreate(*data, flags, this, target);
m_objectData->WriteCreate(flags, data, target, this);
m_sceneObjectData->WriteCreate(flags, data, target, this);
}
void SceneObject::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const
void SceneObject::BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const
{
*data << uint32(m_values.GetChangedObjectTypeMask());
data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
m_objectData->WriteUpdate(flags, data, target, this);
if (m_values.HasChanged(TYPEID_SCENEOBJECT))
m_sceneObjectData->WriteUpdate(*data, flags, this, target);
m_sceneObjectData->WriteUpdate(flags, data, target, this);
}
void SceneObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
@@ -168,14 +168,14 @@ void SceneObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::Objec
ByteBuffer& buffer = PrepareValuesUpdateBuffer(data);
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags);
BuildEntityFragmentsForValuesUpdateForPlayerWithMask(buffer, flags);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
m_objectData->WriteUpdate(requestedObjectMask, buffer, target, this, true);
if (valuesMask[TYPEID_SCENEOBJECT])
m_sceneObjectData->WriteUpdate(buffer, requestedSceneObjectMask, true, this, target);
m_sceneObjectData->WriteUpdate(requestedSceneObjectMask, buffer, target, this, true);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
@@ -193,8 +193,8 @@ void SceneObject::ValuesUpdateForPlayerWithMaskSender::operator()(Player const*
player->SendDirectMessage(&packet);
}
void SceneObject::ClearUpdateMask(bool remove)
void SceneObject::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&SceneObject::m_sceneObjectData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}

View File

@@ -36,9 +36,9 @@ public:
~SceneObject();
protected:
void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void BuildValuesCreate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void BuildValuesUpdate(UF::UpdateFieldFlag flags, ByteBuffer& data, Player const* target) const override;
void ClearValuesChangesMask() override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,

View File

@@ -14107,10 +14107,10 @@ void Unit::DestroyForPlayer(Player const* target) const
WorldObject::DestroyForPlayer(target);
}
void Unit::ClearUpdateMask(bool remove)
void Unit::ClearValuesChangesMask()
{
m_values.ClearChangesMask(&Unit::m_unitData);
Object::ClearUpdateMask(remove);
WorldObject::ClearValuesChangesMask();
}
int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue /*= false*/, int32 miscValue /*= 0*/) const

View File

@@ -1881,7 +1881,7 @@ class TC_GAME_API Unit : public WorldObject
UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const override;
void DestroyForPlayer(Player const* target) const override;
void ClearUpdateMask(bool remove) override;
void ClearValuesChangesMask() override;
void _UpdateSpells(uint32 time);
void _DeleteRemovedAuras();