diff --git a/sql/updates/hotfixes/master/2026_03_12_00_hotfixes.sql b/sql/updates/hotfixes/master/2026_03_12_00_hotfixes.sql new file mode 100644 index 000000000..38abd625c --- /dev/null +++ b/sql/updates/hotfixes/master/2026_03_12_00_hotfixes.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS `initiative_cycle`; +CREATE TABLE `initiative_cycle` ( + `ID` int unsigned NOT NULL DEFAULT '0', + `RewardGroupID` int NOT NULL DEFAULT '0', + `CycleIndex` int NOT NULL DEFAULT '0', + `StartDay` int NOT NULL DEFAULT '0', + `Duration` int NOT NULL DEFAULT '0', + `InitiativeID` int NOT NULL DEFAULT '0', + `VerifiedBuild` int NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index 0e2d688bb..22caa7a89 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -2393,7 +2393,7 @@ void HotfixDatabaseConnection::DoPrepareStatements() // InitiativeCycle.db2 - PrepareStatement(HOTFIX_SEL_INITIATIVE_CYCLE, "SELECT ID, InitiativeID, CycleIndex, StartDay, Duration, Flags FROM initiative_cycle WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); + PrepareStatement(HOTFIX_SEL_INITIATIVE_CYCLE, "SELECT ID, RewardGroupID, CycleIndex, StartDay, Duration, InitiativeID FROM initiative_cycle WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); PREPARE_MAX_ID_STMT(HOTFIX_SEL_INITIATIVE_CYCLE, "SELECT MAX(ID) + 1 FROM initiative_cycle", CONNECTION_SYNCH); // InitiativeCyclePriority.db2 diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index 9de495219..b1b33220a 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -7825,11 +7825,11 @@ struct HouseDecorLoadInfo static constexpr DB2FieldMeta Fields[6] = { {.IsSigned = false, .Type = FT_INT, .Name = "ID" }, - {.IsSigned = true, .Type = FT_INT, .Name = "InitiativeID" }, + {.IsSigned = true, .Type = FT_INT, .Name = "RewardGroupID" }, {.IsSigned = true, .Type = FT_INT, .Name = "CycleIndex" }, {.IsSigned = true, .Type = FT_INT, .Name = "StartDay" }, {.IsSigned = true, .Type = FT_INT, .Name = "Duration" }, - {.IsSigned = true, .Type = FT_INT, .Name = "Flags" }, + {.IsSigned = true, .Type = FT_INT, .Name = "InitiativeID" }, }; static constexpr DB2LoadInfo Instance{ Fields, 6, &InitiativeCycleMeta::Instance, HOTFIX_SEL_INITIATIVE_CYCLE }; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 0d131b651..e9b3e24e9 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -5527,11 +5527,11 @@ struct ExteriorComponentXGroupEntry struct InitiativeCycleEntry { uint32 ID; - int32 InitiativeID; + int32 RewardGroupID; // Unknown FK (values 600-2607), not NeighborhoodInitiative int32 CycleIndex; int32 StartDay; int32 Duration; - int32 Flags; + int32 InitiativeID; // FK -> NeighborhoodInitiative.ID (was mislabeled "Flags") }; struct InitiativeCyclePriorityEntry diff --git a/src/server/game/Entities/Account/Account.cpp b/src/server/game/Entities/Account/Account.cpp index a99b445bf..707bc218f 100644 --- a/src/server/game/Entities/Account/Account.cpp +++ b/src/server/game/Entities/Account/Account.cpp @@ -97,7 +97,7 @@ namespace Battlenet // (e.g., FHousingStorage_C populated by PopulateCatalogStorageEntries) are included. BuildUpdateChangesMask(); BaseEntity::SendUpdateToPlayer(player); - ClearUpdateMask(false); + ClearUpdateMask(true); } void Account::SetHousingDecorStorageEntry(ObjectGuid decorGuid, ObjectGuid houseGuid, uint8 sourceType, std::string sourceValue) diff --git a/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.cpp b/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.cpp index dfe0d8ca2..b405c8de6 100644 --- a/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.cpp +++ b/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.cpp @@ -81,7 +81,7 @@ void HousingNeighborhoodMirrorEntity::SendUpdateToPlayer(Player* player) { BuildUpdateChangesMask(); BaseEntity::SendUpdateToPlayer(player); - ClearUpdateMask(false); + ClearUpdateMask(true); } void HousingNeighborhoodMirrorEntity::SetName(std::string const& name) diff --git a/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.h b/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.h index e94d72a56..56c1a842a 100644 --- a/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.h +++ b/src/server/game/Entities/Housing/HousingNeighborhoodMirrorEntity.h @@ -36,6 +36,9 @@ public: void SendUpdateToPlayer(Player* player); + // Reset the entity GUID (must be called before AddToWorld) + void ResetGuid(ObjectGuid newGuid) { _Create(newGuid); } + // Neighborhood mirror setters void SetName(std::string const& name); void SetOwnerGUID(ObjectGuid ownerGuid); diff --git a/src/server/game/Entities/Housing/HousingPlayerHouseEntity.cpp b/src/server/game/Entities/Housing/HousingPlayerHouseEntity.cpp index 8d342cee3..a3dfcde6e 100644 --- a/src/server/game/Entities/Housing/HousingPlayerHouseEntity.cpp +++ b/src/server/game/Entities/Housing/HousingPlayerHouseEntity.cpp @@ -81,17 +81,7 @@ void HousingPlayerHouseEntity::SendUpdateToPlayer(Player* player) { BuildUpdateChangesMask(); BaseEntity::SendUpdateToPlayer(player); - ClearUpdateMask(false); -} - -void HousingPlayerHouseEntity::SetHouseType(uint32 houseType) -{ - SetUpdateFieldValue(m_values.ModifyValue(&HousingPlayerHouseEntity::m_housingPlayerHouseData).ModifyValue(&UF::HousingPlayerHouseData::HouseType), houseType); -} - -void HousingPlayerHouseEntity::SetHouseSize(uint32 houseSize) -{ - SetUpdateFieldValue(m_values.ModifyValue(&HousingPlayerHouseEntity::m_housingPlayerHouseData).ModifyValue(&UF::HousingPlayerHouseData::HouseSize), houseSize); + ClearUpdateMask(true); } void HousingPlayerHouseEntity::SetPlotIndex(int32 plotIndex) diff --git a/src/server/game/Entities/Housing/HousingPlayerHouseEntity.h b/src/server/game/Entities/Housing/HousingPlayerHouseEntity.h index 0c01b554f..265db4e2c 100644 --- a/src/server/game/Entities/Housing/HousingPlayerHouseEntity.h +++ b/src/server/game/Entities/Housing/HousingPlayerHouseEntity.h @@ -36,9 +36,7 @@ public: void SendUpdateToPlayer(Player* player); - // Housing UpdateField setters - void SetHouseType(uint32 houseType); - void SetHouseSize(uint32 houseSize); + // Housing UpdateField setters (IDA-verified: HouseType/HouseSize not in this fragment) void SetPlotIndex(int32 plotIndex); void SetLevel(uint32 level); void SetFavor(uint64 favor); diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 7a5716786..ee74922ab 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -25,7 +25,7 @@ #include "UpdateFieldImpl.h" #include "ViewerDependentValues.h" -// This file is automatically generated, DO NOT EDIT + // This file is automatically generated, DO NOT EDIT #if TRINITY_COMPILER == TRINITY_COMPILER_GNU #pragma GCC diagnostic push @@ -37,10510 +37,10499 @@ namespace UF { -void ObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << float(Scale); -} - -void ObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void ObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) + void ObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const { - if (changesMask[1]) + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << float(Scale); + } + + void ObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void ObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) { - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[2]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[3]) - { - data << float(Scale); + if (changesMask[1]) + { + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[2]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[3]) + { + data << float(Scale); + } } } -} -void ObjectData::ClearChangesMask() -{ - Base::ClearChangesMask(EntryID); - Base::ClearChangesMask(DynamicFlags); - Base::ClearChangesMask(Scale); - _changesMask.ResetAll(); -} - -void ItemEnchantment::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << int32(ID); - data << uint32(Duration); - data << int16(Charges); - data << uint16(Inactive); -} - -void ItemEnchantment::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 5); - - data.FlushBits(); - if (changesMask[0]) + void ObjectData::ClearChangesMask() { - if (changesMask[1]) + Base::ClearChangesMask(EntryID); + Base::ClearChangesMask(DynamicFlags); + Base::ClearChangesMask(Scale); + _changesMask.ResetAll(); + } + + void ItemEnchantment::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const + { + data << int32(ID); + data << uint32(Duration); + data << int16(Charges); + data << uint16(Inactive); + } + + void ItemEnchantment::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 5); + + data.FlushBits(); + if (changesMask[0]) { - data << int32(ID); - } - if (changesMask[2]) - { - data << uint32(Duration); - } - if (changesMask[3]) - { - data << int16(Charges); - } - if (changesMask[4]) - { - data << uint16(Inactive); + if (changesMask[1]) + { + data << int32(ID); + } + if (changesMask[2]) + { + data << uint32(Duration); + } + if (changesMask[3]) + { + data << int16(Charges); + } + if (changesMask[4]) + { + data << uint16(Inactive); + } } } -} -void ItemEnchantment::ClearChangesMask() -{ - Base::ClearChangesMask(ID); - Base::ClearChangesMask(Duration); - Base::ClearChangesMask(Charges); - Base::ClearChangesMask(Inactive); - _changesMask.ResetAll(); -} - -void ItemMod::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << uint8(Type); - data << int32(Value); -} - -void ItemMod::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << uint8(Type); - data << int32(Value); -} - -bool ItemMod::operator==(ItemMod const& right) const -{ - return Type == right.Type - && Value == right.Value; -} - -void ItemModList::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data.WriteBits(Values.size(), 6); - for (uint32 i = 0; i < Values.size(); ++i) + void ItemEnchantment::ClearChangesMask() { - Values[i].WriteCreate(data, receiver, owner); + Base::ClearChangesMask(ID); + Base::ClearChangesMask(Duration); + Base::ClearChangesMask(Charges); + Base::ClearChangesMask(Inactive); + _changesMask.ResetAll(); } - data.FlushBits(); -} -void ItemModList::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 1); - - if (changesMask[0]) + void ItemMod::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const { - if (!ignoreChangesMask) - Values.WriteUpdateMask(data, 6); - else - WriteCompleteDynamicFieldUpdateMask(Values.size(), data, 6); + data << uint8(Type); + data << int32(Value); } - data.FlushBits(); - if (changesMask[0]) + + void ItemMod::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const { + data << uint8(Type); + data << int32(Value); + } + + bool ItemMod::operator==(ItemMod const& right) const + { + return Type == right.Type + && Value == right.Value; + } + + void ItemModList::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const + { + data.WriteBits(Values.size(), 6); for (uint32 i = 0; i < Values.size(); ++i) { - if (Values.HasChanged(i) || ignoreChangesMask) - { - Values[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } + Values[i].WriteCreate(data, receiver, owner); } - } - data.FlushBits(); -} - -void ItemModList::ClearChangesMask() -{ - Base::ClearChangesMask(Values); - _changesMask.ResetAll(); -} - -void ArtifactPower::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << int16(ArtifactPowerID); - data << uint8(PurchasedRank); - data << uint8(CurrentRankWithBonus); -} - -void ArtifactPower::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << int16(ArtifactPowerID); - data << uint8(PurchasedRank); - data << uint8(CurrentRankWithBonus); -} - -bool ArtifactPower::operator==(ArtifactPower const& right) const -{ - return ArtifactPowerID == right.ArtifactPowerID - && PurchasedRank == right.PurchasedRank - && CurrentRankWithBonus == right.CurrentRankWithBonus; -} - -void SocketedGem::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << int32(ItemID); - for (uint32 i = 0; i < 16; ++i) - { - data << uint16(BonusListIDs[i]); - } - data << uint8(Context); -} - -void SocketedGem::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlocksMask(0), 1); - if (changesMask.GetBlock(0)) - data.WriteBits(changesMask.GetBlock(0), 32); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(ItemID); - } - if (changesMask[2]) - { - data << uint8(Context); - } - } - if (changesMask[3]) - { - for (uint32 i = 0; i < 16; ++i) - { - if (changesMask[4 + i]) - { - data << uint16(BonusListIDs[i]); - } - } - } -} - -void SocketedGem::ClearChangesMask() -{ - Base::ClearChangesMask(ItemID); - Base::ClearChangesMask(Context); - Base::ClearChangesMask(BonusListIDs); - _changesMask.ResetAll(); -} - -void ItemData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - data << *Owner; - data << *ContainedIn; - data << *Creator; - data << *GiftCreator; - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint32(StackCount); - data << uint32(Expiration); - for (uint32 i = 0; i < 5; ++i) - { - data << int32(SpellCharges[i]); - } - } - data << uint32(DynamicFlags); - for (uint32 i = 0; i < 13; ++i) - { - Enchantment[i].WriteCreate(data, receiver, owner); - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint32(Durability); - data << uint32(MaxDurability); - } - data << uint32(CreatePlayedTime); - data << uint8(Context); - data << int64(CreateTime); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint64(ArtifactXP); - data << uint8(ItemAppearanceModID); - } - data << uint32(ArtifactPowers.size()); - data << uint32(Gems.size()); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint32(ZoneFlags); - } - data << *ItemBonusKey; - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint16(DEBUGItemLevel); - } - for (uint32 i = 0; i < ArtifactPowers.size(); ++i) - { - ArtifactPowers[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < Gems.size(); ++i) - { - Gems[i].WriteCreate(data, receiver, owner); - } - Modifiers->WriteCreate(data, receiver, owner); -} - -static constexpr void ItemDataAppendAllowedFieldsMaskForFlag(ItemData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array{ 0x07F58D80u, 0x00000000u }; -} - -void ItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); -} - -void ItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) -{ - Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); - ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - changesMask &= allowedMaskForTarget; -} - -void ItemData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Item const* owner) const -{ - Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); - ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); -} - -void ItemData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Item const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 2); - for (uint32 i = 0; i < 2; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreNestedChangesMask) - ArtifactPowers.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ArtifactPowers.size(), data); - } - if (changesMask[2]) - { - if (!ignoreNestedChangesMask) - Gems.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Gems.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < ArtifactPowers.size(); ++i) - { - if (ArtifactPowers.HasChanged(i) || ignoreNestedChangesMask) - { - ArtifactPowers[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - for (uint32 i = 0; i < Gems.size(); ++i) - { - if (Gems.HasChanged(i) || ignoreNestedChangesMask) - { - Gems[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[3]) - { - data << *Owner; - } - if (changesMask[4]) - { - data << *ContainedIn; - } - if (changesMask[5]) - { - data << *Creator; - } - if (changesMask[6]) - { - data << *GiftCreator; - } - if (changesMask[7]) - { - data << uint32(StackCount); - } - if (changesMask[8]) - { - data << uint32(Expiration); - } - if (changesMask[9]) - { - data << uint32(DynamicFlags); - } - if (changesMask[10]) - { - data << uint32(Durability); - } - if (changesMask[11]) - { - data << uint32(MaxDurability); - } - if (changesMask[12]) - { - data << uint32(CreatePlayedTime); - } - if (changesMask[13]) - { - data << uint8(Context); - } - if (changesMask[14]) - { - data << int64(CreateTime); - } - if (changesMask[15]) - { - data << uint64(ArtifactXP); - } - if (changesMask[16]) - { - data << uint8(ItemAppearanceModID); - } - if (changesMask[18]) - { - data << uint32(ZoneFlags); - } - if (changesMask[19]) - { - data << *ItemBonusKey; - } - if (changesMask[20]) - { - data << uint16(DEBUGItemLevel); - } - if (changesMask[17]) - { - Modifiers->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[21]) - { - for (uint32 i = 0; i < 5; ++i) - { - if (changesMask[22 + i]) - { - data << int32(SpellCharges[i]); - } - } - } - if (changesMask[27]) - { - for (uint32 i = 0; i < 13; ++i) - { - if (changesMask[28 + i]) - { - Enchantment[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } -} - -void ItemData::ClearChangesMask() -{ - Base::ClearChangesMask(ArtifactPowers); - Base::ClearChangesMask(Gems); - Base::ClearChangesMask(Owner); - Base::ClearChangesMask(ContainedIn); - Base::ClearChangesMask(Creator); - Base::ClearChangesMask(GiftCreator); - Base::ClearChangesMask(StackCount); - Base::ClearChangesMask(Expiration); - Base::ClearChangesMask(DynamicFlags); - Base::ClearChangesMask(Durability); - Base::ClearChangesMask(MaxDurability); - Base::ClearChangesMask(CreatePlayedTime); - Base::ClearChangesMask(Context); - Base::ClearChangesMask(CreateTime); - Base::ClearChangesMask(ArtifactXP); - Base::ClearChangesMask(ItemAppearanceModID); - Base::ClearChangesMask(Modifiers); - Base::ClearChangesMask(ZoneFlags); - Base::ClearChangesMask(ItemBonusKey); - Base::ClearChangesMask(DEBUGItemLevel); - Base::ClearChangesMask(SpellCharges); - Base::ClearChangesMask(Enchantment); - _changesMask.ResetAll(); -} - -void ContainerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Bag const* owner) const -{ - for (uint32 i = 0; i < 98; ++i) - { - data << Slots[i]; - } - data << uint32(NumSlots); -} - -void ContainerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Bag const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void ContainerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Bag const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 4); - for (uint32 i = 0; i < 4; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << uint32(NumSlots); - } - } - if (changesMask[2]) - { - for (uint32 i = 0; i < 98; ++i) - { - if (changesMask[3 + i]) - { - data << Slots[i]; - } - } - } -} - -void ContainerData::ClearChangesMask() -{ - Base::ClearChangesMask(NumSlots); - Base::ClearChangesMask(Slots); - _changesMask.ResetAll(); -} - -void AzeriteEmpoweredItemData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteEmpoweredItem const* owner) const -{ - for (uint32 i = 0; i < 5; ++i) - { - data << int32(Selections[i]); - } -} - -void AzeriteEmpoweredItemData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteEmpoweredItem const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void AzeriteEmpoweredItemData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AzeriteEmpoweredItem const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 1); - if (changesMask.GetBlock(0)) - data.WriteBits(changesMask.GetBlock(0), 32); - - data.FlushBits(); - if (changesMask[0]) - { - for (uint32 i = 0; i < 5; ++i) - { - if (changesMask[1 + i]) - { - data << int32(Selections[i]); - } - } - } -} - -void AzeriteEmpoweredItemData::ClearChangesMask() -{ - Base::ClearChangesMask(Selections); - _changesMask.ResetAll(); -} - -void UnlockedAzeriteEssence::WriteCreate(ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const -{ - data << uint32(AzeriteEssenceID); - data << uint32(Rank); -} - -void UnlockedAzeriteEssence::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const -{ - data << uint32(AzeriteEssenceID); - data << uint32(Rank); -} - -bool UnlockedAzeriteEssence::operator==(UnlockedAzeriteEssence const& right) const -{ - return AzeriteEssenceID == right.AzeriteEssenceID - && Rank == right.Rank; -} - -void SelectedAzeriteEssences::WriteCreate(ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const -{ - for (uint32 i = 0; i < 4; ++i) - { - data << uint32(AzeriteEssenceID[i]); - } - data << uint32(SpecializationID); - data.WriteBit(Enabled); - data.FlushBits(); -} - -void SelectedAzeriteEssences::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlocksMask(0), 1); - if (changesMask.GetBlock(0)) - data.WriteBits(changesMask.GetBlock(0), 32); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(Enabled); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - data << uint32(SpecializationID); - } - } - if (changesMask[3]) - { - for (uint32 i = 0; i < 4; ++i) - { - if (changesMask[4 + i]) - { - data << uint32(AzeriteEssenceID[i]); - } - } - } - data.FlushBits(); -} - -void SelectedAzeriteEssences::ClearChangesMask() -{ - Base::ClearChangesMask(Enabled); - Base::ClearChangesMask(SpecializationID); - Base::ClearChangesMask(AzeriteEssenceID); - _changesMask.ResetAll(); -} - -void AzeriteItemData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint64(Xp); - data << uint32(Level); - data << uint32(AuraLevel); - data << uint32(KnowledgeLevel); - data << int32(DEBUGknowledgeWeek); - } - data << uint32(UnlockedEssences.size()); - data << uint32(SelectedEssences.size()); - data << uint32(UnlockedEssenceMilestones.size()); - for (uint32 i = 0; i < UnlockedEssences.size(); ++i) - { - UnlockedEssences[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < UnlockedEssenceMilestones.size(); ++i) - { - data << uint32(UnlockedEssenceMilestones[i]); - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data.WriteBit(Enabled); - } - for (uint32 i = 0; i < SelectedEssences.size(); ++i) - { - SelectedEssences[i].WriteCreate(data, receiver, owner); - } - data.FlushBits(); -} - -static constexpr void AzeriteItemDataAppendAllowedFieldsMaskForFlag(AzeriteItemData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array{ 0x000003E2u }; -} - -void AzeriteItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); -} - -void AzeriteItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) -{ - Mask allowedMaskForTarget({ 0x0000001Du }); - AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - changesMask &= allowedMaskForTarget; -} - -void AzeriteItemData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const -{ - Mask allowedMaskForTarget({ 0x0000001Du }); - AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); -} - -void AzeriteItemData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 10); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(Enabled); - } - if (changesMask[2]) - { - if (!ignoreNestedChangesMask) - UnlockedEssences.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(UnlockedEssences.size(), data); - } - if (changesMask[3]) - { - if (!ignoreNestedChangesMask) - SelectedEssences.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SelectedEssences.size(), data); - } - if (changesMask[4]) - { - if (!ignoreNestedChangesMask) - UnlockedEssenceMilestones.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(UnlockedEssenceMilestones.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - for (uint32 i = 0; i < UnlockedEssences.size(); ++i) - { - if (UnlockedEssences.HasChanged(i) || ignoreNestedChangesMask) - { - UnlockedEssences[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[4]) - { - for (uint32 i = 0; i < UnlockedEssenceMilestones.size(); ++i) - { - if (UnlockedEssenceMilestones.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(UnlockedEssenceMilestones[i]); - } - } - } - if (changesMask[3]) - { - for (uint32 i = 0; i < SelectedEssences.size(); ++i) - { - if (SelectedEssences.HasChanged(i) || ignoreNestedChangesMask) - { - SelectedEssences[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[5]) - { - data << uint64(Xp); - } - if (changesMask[6]) - { - data << uint32(Level); - } - if (changesMask[7]) - { - data << uint32(AuraLevel); - } - if (changesMask[8]) - { - data << uint32(KnowledgeLevel); - } - if (changesMask[9]) - { - data << int32(DEBUGknowledgeWeek); - } - } - data.FlushBits(); -} - -void AzeriteItemData::ClearChangesMask() -{ - Base::ClearChangesMask(Enabled); - Base::ClearChangesMask(UnlockedEssences); - Base::ClearChangesMask(UnlockedEssenceMilestones); - Base::ClearChangesMask(SelectedEssences); - Base::ClearChangesMask(Xp); - Base::ClearChangesMask(Level); - Base::ClearChangesMask(AuraLevel); - Base::ClearChangesMask(KnowledgeLevel); - Base::ClearChangesMask(DEBUGknowledgeWeek); - _changesMask.ResetAll(); -} - -void SpellCastVisual::WriteCreate(ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << int32(SpellXSpellVisualID); - data << int32(ScriptVisualID); -} - -void SpellCastVisual::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << int32(SpellXSpellVisualID); - data << int32(ScriptVisualID); -} - -bool SpellCastVisual::operator==(SpellCastVisual const& right) const -{ - return SpellXSpellVisualID == right.SpellXSpellVisualID - && ScriptVisualID == right.ScriptVisualID; -} - -void UnitChannel::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - data << int32(SpellID); - SpellVisual.WriteCreate(data, receiver, owner); - data << uint32(StartTimeMs); - data << uint32(Duration); -} - -void UnitChannel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - data << int32(SpellID); - SpellVisual.WriteUpdate(ignoreChangesMask, data, receiver, owner); - data << uint32(StartTimeMs); - data << uint32(Duration); -} - -bool UnitChannel::operator==(UnitChannel const& right) const -{ - return SpellID == right.SpellID - && SpellVisual == right.SpellVisual - && StartTimeMs == right.StartTimeMs - && Duration == right.Duration; -} - -void VisibleItem::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - data << int32(ItemID); - data << int32(SecondaryItemModifiedAppearanceID); - data << int32(ConditionalItemAppearanceID); - data << uint16(ItemAppearanceModID); - data << uint16(ItemVisual); - data << uint32(ItemModifiedAppearanceID); - data << uint8(Field_18); - data.WriteBit(HasTransmog); - data.WriteBit(HasIllusion); - data.FlushBits(); -} - -void VisibleItem::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 10); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(HasTransmog); - } - if (changesMask[2]) - { - data.WriteBit(HasIllusion); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - data << int32(ItemID); - } - if (changesMask[4]) - { - data << int32(SecondaryItemModifiedAppearanceID); - } - if (changesMask[5]) - { - data << int32(ConditionalItemAppearanceID); - } - if (changesMask[6]) - { - data << uint16(ItemAppearanceModID); - } - if (changesMask[7]) - { - data << uint16(ItemVisual); - } - if (changesMask[8]) - { - data << uint32(ItemModifiedAppearanceID); - } - if (changesMask[9]) - { - data << uint8(Field_18); - } - } - data.FlushBits(); -} - -void VisibleItem::ClearChangesMask() -{ - Base::ClearChangesMask(HasTransmog); - Base::ClearChangesMask(HasIllusion); - Base::ClearChangesMask(ItemID); - Base::ClearChangesMask(SecondaryItemModifiedAppearanceID); - Base::ClearChangesMask(ConditionalItemAppearanceID); - Base::ClearChangesMask(ItemAppearanceModID); - Base::ClearChangesMask(ItemVisual); - Base::ClearChangesMask(ItemModifiedAppearanceID); - Base::ClearChangesMask(Field_18); - _changesMask.ResetAll(); -} - -void PassiveSpellHistory::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - data << int32(SpellID); - data << int32(AuraSpellID); -} - -void PassiveSpellHistory::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - data << int32(SpellID); - data << int32(AuraSpellID); -} - -bool PassiveSpellHistory::operator==(PassiveSpellHistory const& right) const -{ - return SpellID == right.SpellID - && AuraSpellID == right.AuraSpellID; -} - -void UnitAssistActionData::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - data << uint8(Type); - data << uint32(VirtualRealmAddress); - data.WriteBits(PlayerName->size(), 6); - data.FlushBits(); - data << WorldPackets::SizedString::Data(*PlayerName); -} - -void UnitAssistActionData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << uint8(Type); - } - if (changesMask[3]) - { - data << uint32(VirtualRealmAddress); - } - if (changesMask[2]) - { - data.WriteBits(PlayerName->size(), 6); - data.FlushBits(); - data << WorldPackets::SizedString::Data(*PlayerName); - } - } -} - -void UnitAssistActionData::ClearChangesMask() -{ - Base::ClearChangesMask(Type); - Base::ClearChangesMask(PlayerName); - Base::ClearChangesMask(VirtualRealmAddress); - _changesMask.ResetAll(); -} - -void UnitData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - ViewerDependentValue::value_type stateWorldEffectIDs = {}; - - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); - data << uint32(stateWorldEffectIDs->size()); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << int32(SpellOverrideNameID); - for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) - { - data << uint32((*stateWorldEffectIDs)[i]); - } - data << *Charm; - data << *Summon; - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << *Critter; - } - data << *CharmedBy; - data << *SummonedBy; - data << *CreatedBy; - data << *DemonCreator; - data << *LookAtControllerTarget; - data << *Target; - data << *BattlePetCompanionGUID; - data << uint64(BattlePetDBID); - ChannelData->WriteCreate(data, receiver, owner); - data << int8(SpellEmpowerStage); - data << uint32(SummonedByHomeRealm); - data << uint8(Race); - data << uint8(ClassId); - data << uint8(PlayerClassId); - data << uint8(Sex); - data << uint8(CreatureType); - data << uint8(DisplayPower); - data << uint32(OverrideDisplayPowerID); - data << int64(Health); - for (uint32 i = 0; i < 10; ++i) - { - data << int32(Power[i]); - data << int32(MaxPower[i]); - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::UnitAll)) - { - for (uint32 i = 0; i < 10; ++i) - { - data << float(PowerRegenFlatModifier[i]); - data << float(PowerRegenInterruptedFlatModifier[i]); - } - } - data << int64(MaxHealth); - data << int32(Level); - data << int32(EffectiveLevel); - data << int32(ContentTuningID); - data << int32(ScalingLevelMin); - data << int32(ScalingLevelMax); - data << int32(ScalingLevelDelta); - data << uint8(ScalingFactionGroup); - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - for (uint32 i = 0; i < 2; ++i) - { - data << uint32(AttackRoundBaseTime[i]); - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint32(RangedAttackRoundBaseTime); - } - data << float(BoundingRadius); - data << float(CombatReach); - data << float(DisplayScale); - data << int32(CreatureFamily); - data << uint8(OverrideCreatureType); - data << int32(NativeDisplayID); - data << float(NativeXDisplayScale); - data << int32(MountDisplayID); - data << int32(CosmeticMountDisplayID); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::Empath)) - { - data << float(MinDamage); - data << float(MaxDamage); - data << float(MinOffHandDamage); - data << float(MaxOffHandDamage); - } - data << uint8(StandState); - data << uint8(PetTalentPoints); - data << uint8(VisFlags); - data << uint8(AnimTier); - data << uint32(PetNumber); - data << uint32(PetNameTimestamp); - data << uint32(PetExperience); - data << uint32(PetNextLevelExperience); - data << float(ModCastingSpeed); - data << float(ModCastingSpeedNeg); - data << float(ModSpellHaste); - data << float(ModHaste); - data << float(ModRangedHaste); - data << float(ModHasteRegen); - data << float(ModTimeRate); - data << int32(CreatedBySpell); - data << int32(EmoteState); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - for (uint32 i = 0; i < 5; ++i) - { - data << int32(Stats[i]); - data << int32(StatPosBuff[i]); - data << int32(StatNegBuff[i]); - data << int32(StatSupportBuff[i]); - } - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::Empath)) - { - for (uint32 i = 0; i < 7; ++i) - { - data << int32(Resistances[i]); - } - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - for (uint32 i = 0; i < 7; ++i) - { - data << int32(BonusResistanceMods[i]); - data << int32(ManaCostModifier[i]); - } - } - data << int32(BaseMana); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << int32(BaseHealth); - } - data << uint8(SheatheState); - data << uint8(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint8(PetFlags); - data << uint8(ShapeshiftForm); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << int32(AttackPower); - data << int32(AttackPowerModPos); - data << int32(AttackPowerModNeg); - data << float(AttackPowerMultiplier); - data << int32(AttackPowerModSupport); - data << int32(RangedAttackPower); - data << int32(RangedAttackPowerModPos); - data << int32(RangedAttackPowerModNeg); - data << float(RangedAttackPowerMultiplier); - data << int32(RangedAttackPowerModSupport); - data << int32(MainHandWeaponAttackPower); - data << int32(OffHandWeaponAttackPower); - data << int32(RangedWeaponAttackPower); - data << int32(SetAttackSpeedAura); - data << float(Lifesteal); - data << float(MinRangedDamage); - data << float(MaxRangedDamage); - data << float(ManaCostMultiplier); - } - data << float(MaxHealthModifier); - data << float(HoverHeight); - data << int32(MinItemLevelCutoff); - data << int32(MinItemLevel); - data << int32(MaxItemLevel); - data << int32(AzeriteItemLevel); - data << int32(WildBattlePetLevel); - data << int32(BattlePetCompanionExperience); - data << uint32(BattlePetCompanionNameTimestamp); - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << int32(ScaleDuration); - data << int32(LooksLikeMountID); - data << int32(LooksLikeCreatureID); - data << int32(LookAtControllerID); - data << int32(PerksVendorItemID); - data << int32(TaxiNodesID); - data << *GuildGUID; - data << uint32(PassiveSpells.size()); - data << uint32(WorldEffects.size()); - data << uint32(ChannelObjects.size()); - data << int32(FlightCapabilityID); - data << float(GlideEventSpeedDivisor); - data << int32(DriveCapabilityID); - data << int32(MaxHealthModifierFlatNeg); - data << int32(MaxHealthModifierFlatPos); - data << uint32(SilencedSchoolMask); - data << uint32(CurrentAreaID); - data << float(NameplateDistanceMod); - data << float(AutoAttackRangeMod); - data << *NameplateAttachToGUID; - for (uint32 i = 0; i < PassiveSpells.size(); ++i) - { - PassiveSpells[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < WorldEffects.size(); ++i) - { - data << int32(WorldEffects[i]); - } - for (uint32 i = 0; i < ChannelObjects.size(); ++i) - { - data << ChannelObjects[i]; - } - for (uint32 i = 0; i < 3; ++i) - { - VirtualItems[i].WriteCreate(data, receiver, owner); - } - data.FlushBits(); - data.WriteBit(Field_314); - data.WriteBits(AssistActionData.has_value(), 1); - if (AssistActionData.has_value()) - { - AssistActionData->WriteCreate(data, receiver, owner); - } - data.FlushBits(); -} - -static constexpr void UnitDataAppendAllowedFieldsMaskForFlag(UnitData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array{ 0x00010000u, 0xE0080000u, 0xFE100002u, 0x00000FFEu, 0xC0000200u, 0xFE03FFFFu, 0xFFFFFFFFu, 0x0000000Fu }; - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) - allowedMaskForTarget |= std::array{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xC0000200u, 0x0003FFFFu, 0x00000000u, 0x00000000u }; - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) - allowedMaskForTarget |= std::array{ 0x00000000u, 0xE0000000u, 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u, 0x003FC000u, 0x00000000u }; -} - -void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); -} - -void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) -{ - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x1FF7FFFFu, 0x01EFFFFDu, 0xFFFFF001u, 0x3FFFFFFFu, 0x01FC0000u, 0x00000000u, 0x00000000u }); - UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - changesMask &= allowedMaskForTarget; -} - -void UnitData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Unit const* owner) const -{ - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x1FF7FFFFu, 0x01EFFFFDu, 0xFFFFF001u, 0x3FFFFFFFu, 0x01FC0000u, 0x00000000u, 0x00000000u }); - UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); -} - -void UnitData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Unit const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 8); - for (uint32 i = 0; i < 8; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - ViewerDependentValue::value_type stateWorldEffectIDs = {}; - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(Field_314); - } - if (changesMask[2]) - { - stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); - data.WriteBits(stateWorldEffectIDs->size(), 32); - for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) - { - data << uint32((*stateWorldEffectIDs)[i]); - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - if (!ignoreNestedChangesMask) - PassiveSpells.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(PassiveSpells.size(), data); - } - if (changesMask[4]) - { - if (!ignoreNestedChangesMask) - WorldEffects.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(WorldEffects.size(), data); - } - if (changesMask[5]) - { - if (!ignoreNestedChangesMask) - ChannelObjects.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ChannelObjects.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - for (uint32 i = 0; i < PassiveSpells.size(); ++i) - { - if (PassiveSpells.HasChanged(i) || ignoreNestedChangesMask) - { - PassiveSpells[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[4]) - { - for (uint32 i = 0; i < WorldEffects.size(); ++i) - { - if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(WorldEffects[i]); - } - } - } - if (changesMask[5]) - { - for (uint32 i = 0; i < ChannelObjects.size(); ++i) - { - if (ChannelObjects.HasChanged(i) || ignoreNestedChangesMask) - { - data << ChannelObjects[i]; - } - } - } - if (changesMask[6]) - { - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[7]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[8]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[9]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[10]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[11]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[12]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[13]) - { - data << int32(SpellOverrideNameID); - } - if (changesMask[14]) - { - data << *Charm; - } - if (changesMask[15]) - { - data << *Summon; - } - if (changesMask[16]) - { - data << *Critter; - } - if (changesMask[17]) - { - data << *CharmedBy; - } - if (changesMask[18]) - { - data << *SummonedBy; - } - if (changesMask[19]) - { - data << *CreatedBy; - } - if (changesMask[20]) - { - data << *DemonCreator; - } - if (changesMask[21]) - { - data << *LookAtControllerTarget; - } - if (changesMask[22]) - { - data << *Target; - } - if (changesMask[23]) - { - data << *BattlePetCompanionGUID; - } - if (changesMask[24]) - { - data << uint64(BattlePetDBID); - } - if (changesMask[25]) - { - ChannelData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[26]) - { - data << int8(SpellEmpowerStage); - } - if (changesMask[27]) - { - data << uint32(SummonedByHomeRealm); - } - if (changesMask[28]) - { - data << uint8(Race); - } - if (changesMask[29]) - { - data << uint8(ClassId); - } - if (changesMask[30]) - { - data << uint8(PlayerClassId); - } - if (changesMask[31]) - { - data << uint8(Sex); - } - } - if (changesMask[32]) - { - if (changesMask[33]) - { - data << uint8(CreatureType); - } - if (changesMask[34]) - { - data << uint8(DisplayPower); - } - if (changesMask[35]) - { - data << uint32(OverrideDisplayPowerID); - } - if (changesMask[36]) - { - data << int64(Health); - } - if (changesMask[37]) - { - data << int64(MaxHealth); - } - if (changesMask[38]) - { - data << int32(Level); - } - if (changesMask[39]) - { - data << int32(EffectiveLevel); - } - if (changesMask[40]) - { - data << int32(ContentTuningID); - } - if (changesMask[41]) - { - data << int32(ScalingLevelMin); - } - if (changesMask[42]) - { - data << int32(ScalingLevelMax); - } - if (changesMask[43]) - { - data << int32(ScalingLevelDelta); - } - if (changesMask[44]) - { - data << uint8(ScalingFactionGroup); - } - if (changesMask[45]) - { - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[46]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[47]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[48]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[49]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[50]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[51]) - { - data << uint32(RangedAttackRoundBaseTime); - } - if (changesMask[52]) - { - data << float(BoundingRadius); - } - if (changesMask[53]) - { - data << float(CombatReach); - } - if (changesMask[54]) - { - data << float(DisplayScale); - } - if (changesMask[55]) - { - data << int32(CreatureFamily); - } - if (changesMask[56]) - { - data << uint8(OverrideCreatureType); - } - if (changesMask[57]) - { - data << int32(NativeDisplayID); - } - if (changesMask[58]) - { - data << float(NativeXDisplayScale); - } - if (changesMask[59]) - { - data << int32(MountDisplayID); - } - if (changesMask[60]) - { - data << int32(CosmeticMountDisplayID); - } - if (changesMask[61]) - { - data << float(MinDamage); - } - if (changesMask[62]) - { - data << float(MaxDamage); - } - if (changesMask[63]) - { - data << float(MinOffHandDamage); - } - } - if (changesMask[64]) - { - if (changesMask[65]) - { - data << float(MaxOffHandDamage); - } - if (changesMask[66]) - { - data << uint8(StandState); - } - if (changesMask[67]) - { - data << uint8(PetTalentPoints); - } - if (changesMask[68]) - { - data << uint8(VisFlags); - } - if (changesMask[69]) - { - data << uint8(AnimTier); - } - if (changesMask[70]) - { - data << uint32(PetNumber); - } - if (changesMask[71]) - { - data << uint32(PetNameTimestamp); - } - if (changesMask[72]) - { - data << uint32(PetExperience); - } - if (changesMask[73]) - { - data << uint32(PetNextLevelExperience); - } - if (changesMask[74]) - { - data << float(ModCastingSpeed); - } - if (changesMask[75]) - { - data << float(ModCastingSpeedNeg); - } - if (changesMask[76]) - { - data << float(ModSpellHaste); - } - if (changesMask[77]) - { - data << float(ModHaste); - } - if (changesMask[78]) - { - data << float(ModRangedHaste); - } - if (changesMask[79]) - { - data << float(ModHasteRegen); - } - if (changesMask[80]) - { - data << float(ModTimeRate); - } - if (changesMask[81]) - { - data << int32(CreatedBySpell); - } - if (changesMask[82]) - { - data << int32(EmoteState); - } - if (changesMask[83]) - { - data << int32(BaseMana); - } - if (changesMask[84]) - { - data << int32(BaseHealth); - } - if (changesMask[85]) - { - data << uint8(SheatheState); - } - if (changesMask[86]) - { - data << uint8(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[87]) - { - data << uint8(PetFlags); - } - if (changesMask[88]) - { - data << uint8(ShapeshiftForm); - } - if (changesMask[89]) - { - data << int32(AttackPower); - } - if (changesMask[90]) - { - data << int32(AttackPowerModPos); - } - if (changesMask[91]) - { - data << int32(AttackPowerModNeg); - } - if (changesMask[92]) - { - data << float(AttackPowerMultiplier); - } - if (changesMask[93]) - { - data << int32(AttackPowerModSupport); - } - if (changesMask[94]) - { - data << int32(RangedAttackPower); - } - if (changesMask[95]) - { - data << int32(RangedAttackPowerModPos); - } - } - if (changesMask[96]) - { - if (changesMask[97]) - { - data << int32(RangedAttackPowerModNeg); - } - if (changesMask[98]) - { - data << float(RangedAttackPowerMultiplier); - } - if (changesMask[99]) - { - data << int32(RangedAttackPowerModSupport); - } - if (changesMask[100]) - { - data << int32(MainHandWeaponAttackPower); - } - if (changesMask[101]) - { - data << int32(OffHandWeaponAttackPower); - } - if (changesMask[102]) - { - data << int32(RangedWeaponAttackPower); - } - if (changesMask[103]) - { - data << int32(SetAttackSpeedAura); - } - if (changesMask[104]) - { - data << float(Lifesteal); - } - if (changesMask[105]) - { - data << float(MinRangedDamage); - } - if (changesMask[106]) - { - data << float(MaxRangedDamage); - } - if (changesMask[107]) - { - data << float(ManaCostMultiplier); - } - if (changesMask[108]) - { - data << float(MaxHealthModifier); - } - if (changesMask[109]) - { - data << float(HoverHeight); - } - if (changesMask[110]) - { - data << int32(MinItemLevelCutoff); - } - if (changesMask[111]) - { - data << int32(MinItemLevel); - } - if (changesMask[112]) - { - data << int32(MaxItemLevel); - } - if (changesMask[113]) - { - data << int32(AzeriteItemLevel); - } - if (changesMask[114]) - { - data << int32(WildBattlePetLevel); - } - if (changesMask[115]) - { - data << int32(BattlePetCompanionExperience); - } - if (changesMask[116]) - { - data << uint32(BattlePetCompanionNameTimestamp); - } - if (changesMask[117]) - { - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[118]) - { - data << int32(ScaleDuration); - } - if (changesMask[119]) - { - data << int32(LooksLikeMountID); - } - if (changesMask[120]) - { - data << int32(LooksLikeCreatureID); - } - if (changesMask[121]) - { - data << int32(LookAtControllerID); - } - if (changesMask[122]) - { - data << int32(PerksVendorItemID); - } - if (changesMask[123]) - { - data << int32(TaxiNodesID); - } - if (changesMask[124]) - { - data << *GuildGUID; - } - if (changesMask[125]) - { - data << int32(FlightCapabilityID); - } - if (changesMask[126]) - { - data << float(GlideEventSpeedDivisor); - } - if (changesMask[127]) - { - data << int32(DriveCapabilityID); - } - } - if (changesMask[128]) - { - if (changesMask[129]) - { - data << int32(MaxHealthModifierFlatNeg); - } - if (changesMask[130]) - { - data << int32(MaxHealthModifierFlatPos); - } - if (changesMask[131]) - { - data << uint32(SilencedSchoolMask); - } - if (changesMask[132]) - { - data << uint32(CurrentAreaID); - } - if (changesMask[133]) - { - data << float(NameplateDistanceMod); - } - if (changesMask[134]) - { - data << float(AutoAttackRangeMod); - } - if (changesMask[135]) - { - data << *NameplateAttachToGUID; - } - data.WriteBits(AssistActionData.has_value(), 1); data.FlushBits(); - if (changesMask[136]) - { - if (AssistActionData.has_value()) - { - AssistActionData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } } - if (changesMask[137]) + + void ItemModList::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const { - for (uint32 i = 0; i < 10; ++i) - { - if (changesMask[138 + i]) - { - data << int32(Power[i]); - } - if (changesMask[148 + i]) - { - data << int32(MaxPower[i]); - } - if (changesMask[158 + i]) - { - data << float(PowerRegenFlatModifier[i]); - } - if (changesMask[168 + i]) - { - data << float(PowerRegenInterruptedFlatModifier[i]); - } - } - } - if (changesMask[182]) - { - for (uint32 i = 0; i < 2; ++i) - { - if (changesMask[183 + i]) - { - data << uint32(AttackRoundBaseTime[i]); - } - } - } - if (changesMask[185]) - { - for (uint32 i = 0; i < 5; ++i) - { - if (changesMask[186 + i]) - { - data << int32(Stats[i]); - } - if (changesMask[191 + i]) - { - data << int32(StatPosBuff[i]); - } - if (changesMask[196 + i]) - { - data << int32(StatNegBuff[i]); - } - if (changesMask[201 + i]) - { - data << int32(StatSupportBuff[i]); - } - } - } - if (changesMask[206]) - { - for (uint32 i = 0; i < 7; ++i) - { - if (changesMask[207 + i]) - { - data << int32(Resistances[i]); - } - if (changesMask[214 + i]) - { - data << int32(BonusResistanceMods[i]); - } - if (changesMask[221 + i]) - { - data << int32(ManaCostModifier[i]); - } - } - } - if (changesMask[178]) - { - for (uint32 i = 0; i < 3; ++i) - { - if (changesMask[179 + i]) - { - VirtualItems[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - data.FlushBits(); -} + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); -void UnitData::ClearChangesMask() -{ - Base::ClearChangesMask(Field_314); - Base::ClearChangesMask(StateWorldEffectIDs); - Base::ClearChangesMask(PassiveSpells); - Base::ClearChangesMask(WorldEffects); - Base::ClearChangesMask(ChannelObjects); - Base::ClearChangesMask(DisplayID); - Base::ClearChangesMask(NpcFlags); - Base::ClearChangesMask(NpcFlags2); - Base::ClearChangesMask(StateSpellVisualID); - Base::ClearChangesMask(StateAnimID); - Base::ClearChangesMask(StateAnimKitID); - Base::ClearChangesMask(StateWorldEffectsQuestObjectiveID); - Base::ClearChangesMask(SpellOverrideNameID); - Base::ClearChangesMask(Charm); - Base::ClearChangesMask(Summon); - Base::ClearChangesMask(Critter); - Base::ClearChangesMask(CharmedBy); - Base::ClearChangesMask(SummonedBy); - Base::ClearChangesMask(CreatedBy); - Base::ClearChangesMask(DemonCreator); - Base::ClearChangesMask(LookAtControllerTarget); - Base::ClearChangesMask(Target); - Base::ClearChangesMask(BattlePetCompanionGUID); - Base::ClearChangesMask(BattlePetDBID); - Base::ClearChangesMask(ChannelData); - Base::ClearChangesMask(SpellEmpowerStage); - Base::ClearChangesMask(SummonedByHomeRealm); - Base::ClearChangesMask(Race); - Base::ClearChangesMask(ClassId); - Base::ClearChangesMask(PlayerClassId); - Base::ClearChangesMask(Sex); - Base::ClearChangesMask(CreatureType); - Base::ClearChangesMask(DisplayPower); - Base::ClearChangesMask(OverrideDisplayPowerID); - Base::ClearChangesMask(Health); - Base::ClearChangesMask(MaxHealth); - Base::ClearChangesMask(Level); - Base::ClearChangesMask(EffectiveLevel); - Base::ClearChangesMask(ContentTuningID); - Base::ClearChangesMask(ScalingLevelMin); - Base::ClearChangesMask(ScalingLevelMax); - Base::ClearChangesMask(ScalingLevelDelta); - Base::ClearChangesMask(ScalingFactionGroup); - Base::ClearChangesMask(FactionTemplate); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(Flags2); - Base::ClearChangesMask(Flags3); - Base::ClearChangesMask(Flags4); - Base::ClearChangesMask(AuraState); - Base::ClearChangesMask(RangedAttackRoundBaseTime); - Base::ClearChangesMask(BoundingRadius); - Base::ClearChangesMask(CombatReach); - Base::ClearChangesMask(DisplayScale); - Base::ClearChangesMask(CreatureFamily); - Base::ClearChangesMask(OverrideCreatureType); - Base::ClearChangesMask(NativeDisplayID); - Base::ClearChangesMask(NativeXDisplayScale); - Base::ClearChangesMask(MountDisplayID); - Base::ClearChangesMask(CosmeticMountDisplayID); - Base::ClearChangesMask(MinDamage); - Base::ClearChangesMask(MaxDamage); - Base::ClearChangesMask(MinOffHandDamage); - Base::ClearChangesMask(MaxOffHandDamage); - Base::ClearChangesMask(StandState); - Base::ClearChangesMask(PetTalentPoints); - Base::ClearChangesMask(VisFlags); - Base::ClearChangesMask(AnimTier); - Base::ClearChangesMask(PetNumber); - Base::ClearChangesMask(PetNameTimestamp); - Base::ClearChangesMask(PetExperience); - Base::ClearChangesMask(PetNextLevelExperience); - Base::ClearChangesMask(ModCastingSpeed); - Base::ClearChangesMask(ModCastingSpeedNeg); - Base::ClearChangesMask(ModSpellHaste); - Base::ClearChangesMask(ModHaste); - Base::ClearChangesMask(ModRangedHaste); - Base::ClearChangesMask(ModHasteRegen); - Base::ClearChangesMask(ModTimeRate); - Base::ClearChangesMask(CreatedBySpell); - Base::ClearChangesMask(EmoteState); - Base::ClearChangesMask(BaseMana); - Base::ClearChangesMask(BaseHealth); - Base::ClearChangesMask(SheatheState); - Base::ClearChangesMask(PvpFlags); - Base::ClearChangesMask(PetFlags); - Base::ClearChangesMask(ShapeshiftForm); - Base::ClearChangesMask(AttackPower); - Base::ClearChangesMask(AttackPowerModPos); - Base::ClearChangesMask(AttackPowerModNeg); - Base::ClearChangesMask(AttackPowerMultiplier); - Base::ClearChangesMask(AttackPowerModSupport); - Base::ClearChangesMask(RangedAttackPower); - Base::ClearChangesMask(RangedAttackPowerModPos); - Base::ClearChangesMask(RangedAttackPowerModNeg); - Base::ClearChangesMask(RangedAttackPowerMultiplier); - Base::ClearChangesMask(RangedAttackPowerModSupport); - Base::ClearChangesMask(MainHandWeaponAttackPower); - Base::ClearChangesMask(OffHandWeaponAttackPower); - Base::ClearChangesMask(RangedWeaponAttackPower); - Base::ClearChangesMask(SetAttackSpeedAura); - Base::ClearChangesMask(Lifesteal); - Base::ClearChangesMask(MinRangedDamage); - Base::ClearChangesMask(MaxRangedDamage); - Base::ClearChangesMask(ManaCostMultiplier); - Base::ClearChangesMask(MaxHealthModifier); - Base::ClearChangesMask(HoverHeight); - Base::ClearChangesMask(MinItemLevelCutoff); - Base::ClearChangesMask(MinItemLevel); - Base::ClearChangesMask(MaxItemLevel); - Base::ClearChangesMask(AzeriteItemLevel); - Base::ClearChangesMask(WildBattlePetLevel); - Base::ClearChangesMask(BattlePetCompanionExperience); - Base::ClearChangesMask(BattlePetCompanionNameTimestamp); - Base::ClearChangesMask(InteractSpellID); - Base::ClearChangesMask(ScaleDuration); - Base::ClearChangesMask(LooksLikeMountID); - Base::ClearChangesMask(LooksLikeCreatureID); - Base::ClearChangesMask(LookAtControllerID); - Base::ClearChangesMask(PerksVendorItemID); - Base::ClearChangesMask(TaxiNodesID); - Base::ClearChangesMask(GuildGUID); - Base::ClearChangesMask(FlightCapabilityID); - Base::ClearChangesMask(GlideEventSpeedDivisor); - Base::ClearChangesMask(DriveCapabilityID); - Base::ClearChangesMask(MaxHealthModifierFlatNeg); - Base::ClearChangesMask(MaxHealthModifierFlatPos); - Base::ClearChangesMask(SilencedSchoolMask); - Base::ClearChangesMask(CurrentAreaID); - Base::ClearChangesMask(NameplateDistanceMod); - Base::ClearChangesMask(AutoAttackRangeMod); - Base::ClearChangesMask(NameplateAttachToGUID); - Base::ClearChangesMask(AssistActionData); - Base::ClearChangesMask(Power); - Base::ClearChangesMask(MaxPower); - Base::ClearChangesMask(PowerRegenFlatModifier); - Base::ClearChangesMask(PowerRegenInterruptedFlatModifier); - Base::ClearChangesMask(VirtualItems); - Base::ClearChangesMask(AttackRoundBaseTime); - Base::ClearChangesMask(Stats); - Base::ClearChangesMask(StatPosBuff); - Base::ClearChangesMask(StatNegBuff); - Base::ClearChangesMask(StatSupportBuff); - Base::ClearChangesMask(Resistances); - Base::ClearChangesMask(BonusResistanceMods); - Base::ClearChangesMask(ManaCostModifier); - _changesMask.ResetAll(); -} + data.WriteBits(changesMask.GetBlock(0), 1); -void ChrCustomizationChoice::WriteCreate(ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << uint32(ChrCustomizationOptionID); - data << uint32(ChrCustomizationChoiceID); -} - -void ChrCustomizationChoice::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << uint32(ChrCustomizationOptionID); - data << uint32(ChrCustomizationChoiceID); -} - -bool ChrCustomizationChoice::operator==(ChrCustomizationChoice const& right) const -{ - return ChrCustomizationOptionID == right.ChrCustomizationOptionID - && ChrCustomizationChoiceID == right.ChrCustomizationChoiceID; -} - -void QuestLog::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(QuestID); - data << uint16(StateFlags); - for (uint32 i = 0; i < 24; ++i) - { - data << int16(ObjectiveProgress[i]); - } - data << int64(EndTime); - data << uint32(ObjectiveFlags); - data << uint32(EnabledObjectivesMask); -} - -void QuestLog::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlocksMask(0), 1); - if (changesMask.GetBlock(0)) - data.WriteBits(changesMask.GetBlock(0), 32); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(QuestID); - } - if (changesMask[2]) - { - data << uint16(StateFlags); - } - if (changesMask[3]) - { - data << int64(EndTime); - } - if (changesMask[4]) - { - data << uint32(ObjectiveFlags); - } - if (changesMask[5]) - { - data << uint32(EnabledObjectivesMask); - } - } - if (changesMask[6]) - { - for (uint32 i = 0; i < 24; ++i) - { - if (changesMask[7 + i]) - { - data << int16(ObjectiveProgress[i]); - } - } - } -} - -void QuestLog::ClearChangesMask() -{ - Base::ClearChangesMask(QuestID); - Base::ClearChangesMask(StateFlags); - Base::ClearChangesMask(EndTime); - Base::ClearChangesMask(ObjectiveFlags); - Base::ClearChangesMask(EnabledObjectivesMask); - Base::ClearChangesMask(ObjectiveProgress); - _changesMask.ResetAll(); -} - -void ArenaCooldown::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellID); - data << int32(Charges); - data << uint32(Flags); - data << uint32(StartTime); - data << uint32(EndTime); - data << uint32(NextChargeTime); - data << uint8(MaxCharges); -} - -void ArenaCooldown::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 8); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(SpellID); - } - if (changesMask[2]) - { - data << int32(Charges); - } - if (changesMask[3]) - { - data << uint32(Flags); - } - if (changesMask[4]) - { - data << uint32(StartTime); - } - if (changesMask[5]) - { - data << uint32(EndTime); - } - if (changesMask[6]) - { - data << uint32(NextChargeTime); - } - if (changesMask[7]) - { - data << uint8(MaxCharges); - } - } -} - -void ArenaCooldown::ClearChangesMask() -{ - Base::ClearChangesMask(SpellID); - Base::ClearChangesMask(Charges); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(StartTime); - Base::ClearChangesMask(EndTime); - Base::ClearChangesMask(NextChargeTime); - Base::ClearChangesMask(MaxCharges); - _changesMask.ResetAll(); -} - -void ZonePlayerForcedReaction::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(FactionID); - data << int32(Reaction); -} - -void ZonePlayerForcedReaction::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(FactionID); - } - if (changesMask[2]) - { - data << int32(Reaction); - } - } -} - -void ZonePlayerForcedReaction::ClearChangesMask() -{ - Base::ClearChangesMask(FactionID); - Base::ClearChangesMask(Reaction); - _changesMask.ResetAll(); -} - -void PetCreatureName::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(CreatureID); - data.WriteBits(Name->size(), 8); - data << WorldPackets::SizedString::Data(*Name); - data.FlushBits(); -} - -void PetCreatureName::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << uint32(CreatureID); - } - if (changesMask[2]) - { - data.WriteBits(Name->size(), 8); - data << WorldPackets::SizedString::Data(*Name); - } - } - data.FlushBits(); -} - -void PetCreatureName::ClearChangesMask() -{ - Base::ClearChangesMask(CreatureID); - Base::ClearChangesMask(Name); - _changesMask.ResetAll(); -} - -void CTROptions::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(ConditionalFlags.size()); - data << uint8(FactionGroup); - data << uint32(ChromieTimeExpansionMask); - for (uint32 i = 0; i < ConditionalFlags.size(); ++i) - { - data << uint32(ConditionalFlags[i]); - } -} - -void CTROptions::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(ConditionalFlags.size()); - data.FlushBits(); - data << uint8(FactionGroup); - data << uint32(ChromieTimeExpansionMask); - for (uint32 i = 0; i < ConditionalFlags.size(); ++i) - { - data << uint32(ConditionalFlags[i]); - } -} - -bool CTROptions::operator==(CTROptions const& right) const -{ - return ConditionalFlags == right.ConditionalFlags - && FactionGroup == right.FactionGroup - && ChromieTimeExpansionMask == right.ChromieTimeExpansionMask; -} - -void LeaverInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << BnetAccountGUID; - data << float(LeaveScore); - data << uint32(SeasonID); - data << uint32(TotalLeaves); - data << uint32(TotalSuccesses); - data << int32(ConsecutiveSuccesses); - data << int64(LastPenaltyTime); - data << int64(LeaverExpirationTime); - data << int32(Flags); - data.WriteBit(IsLeaver); - data.FlushBits(); -} - -void LeaverInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data.FlushBits(); - data << BnetAccountGUID; - data << float(LeaveScore); - data << uint32(SeasonID); - data << uint32(TotalLeaves); - data << uint32(TotalSuccesses); - data << int32(ConsecutiveSuccesses); - data << int64(LastPenaltyTime); - data << int64(LeaverExpirationTime); - data << int32(Flags); - data.WriteBit(IsLeaver); - data.FlushBits(); -} - -bool LeaverInfo::operator==(LeaverInfo const& right) const -{ - return IsLeaver == right.IsLeaver - && BnetAccountGUID == right.BnetAccountGUID - && LeaveScore == right.LeaveScore - && SeasonID == right.SeasonID - && TotalLeaves == right.TotalLeaves - && TotalSuccesses == right.TotalSuccesses - && ConsecutiveSuccesses == right.ConsecutiveSuccesses - && LastPenaltyTime == right.LastPenaltyTime - && LeaverExpirationTime == right.LeaverExpirationTime - && Flags == right.Flags; -} - -void DeclinedNames::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - for (uint32 i = 0; i < 5; ++i) - { - data.WriteBits(Name[i].size(), 10); - } - for (uint32 i = 0; i < 5; ++i) - { - data << WorldPackets::SizedString::Data(Name[i]); - } - data.FlushBits(); -} - -void DeclinedNames::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlocksMask(0), 1); - if (changesMask.GetBlock(0)) - data.WriteBits(changesMask.GetBlock(0), 32); - - if (changesMask[0]) - { - for (uint32 i = 0; i < 5; ++i) - { - if (changesMask[1 + i]) - { - data.WriteBits(Name[i].size(), 10); - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - for (uint32 i = 0; i < 5; ++i) - { - if (changesMask[1 + i]) - { - data << WorldPackets::SizedString::Data(Name[i]); - } - } - } - data.FlushBits(); -} - -void DeclinedNames::ClearChangesMask() -{ - Base::ClearChangesMask(Name); - _changesMask.ResetAll(); -} - -void CustomTabardInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(EmblemStyle); - data << int32(EmblemColor); - data << int32(BorderStyle); - data << int32(BorderColor); - data << int32(BackgroundColor); -} - -void CustomTabardInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 6); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(EmblemStyle); - } - if (changesMask[2]) - { - data << int32(EmblemColor); - } - if (changesMask[3]) - { - data << int32(BorderStyle); - } - if (changesMask[4]) - { - data << int32(BorderColor); - } - if (changesMask[5]) - { - data << int32(BackgroundColor); - } - } -} - -void CustomTabardInfo::ClearChangesMask() -{ - Base::ClearChangesMask(EmblemStyle); - Base::ClearChangesMask(EmblemColor); - Base::ClearChangesMask(BorderStyle); - Base::ClearChangesMask(BorderColor); - Base::ClearChangesMask(BackgroundColor); - _changesMask.ResetAll(); -} - -void NPCAsPlayerInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << int32(CharacterLoadoutID); - data << int32(CreatureID); - data << LocWorldSpace; - data << float(FacingWorldSpace); - data << TransportGUID; -} - -void NPCAsPlayerInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << int32(CharacterLoadoutID); - data << int32(CreatureID); - data << LocWorldSpace; - data << float(FacingWorldSpace); - data << TransportGUID; -} - -bool NPCAsPlayerInfo::operator==(NPCAsPlayerInfo const& right) const -{ - return Field_0 == right.Field_0 - && CharacterLoadoutID == right.CharacterLoadoutID - && CreatureID == right.CreatureID - && LocWorldSpace == right.LocWorldSpace - && FacingWorldSpace == right.FacingWorldSpace - && TransportGUID == right.TransportGUID; -} - -void PlayerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << *DuelArbiter; - data << *WowAccount; - data << *BnetAccount; - data << uint64(GuildClubMemberID); - data << *LootTargetGUID; - data << uint32(PlayerFlags); - data << uint32(PlayerFlagsEx); - data << uint32(GuildRankID); - data << uint32(GuildDeleteDate); - data << int32(GuildLevel); - data << uint32(Customizations.size()); - data << uint32(RandomCustomizations.size()); - for (uint32 i = 0; i < 2; ++i) - { - data << uint8(PartyType[i]); - } - data << uint8(NativeSex); - data << uint8(Inebriation); - data << uint8(PvpTitle); - data << uint8(ArenaFaction); - data << uint32(DuelTeam); - data << int32(GuildTimeStamp); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - { - for (uint32 i = 0; i < 175; ++i) - { - QuestLog[i].WriteCreate(data, receiver, owner); - } - data << uint32(QuestSessionQuestLog.size()); - } - data << int32(PlayerTitle); - data << int32(FakeInebriation); - data << uint32(VirtualPlayerRealm); - data << uint32(CurrentSpecID); - data << int32(CurrentCombatTraitConfigSubTreeID); - data << int32(TaxiMountAnimKitID); - for (uint32 i = 0; i < 6; ++i) - { - data << float(AvgItemLevel[i]); - } - data << uint8(CurrentBattlePetBreedQuality); - data << int32(HonorLevel); - data << int64(LogoutTime); - data << uint32(ArenaCooldowns.size()); - for (uint32 i = 0; i < 32; ++i) - { - ForcedReactions[i].WriteCreate(data, receiver, owner); - } - data << int32(OfferedAdvJournalQuestID); - data << int32(OfferedScriptQuestID); - data << int32(CurrentBattlePetSpeciesID); - data << uint32(PetNames.size()); - CtrOptions->WriteCreate(data, receiver, owner); - data << int32(CovenantID); - data << int32(SoulbindID); - data << *SpectateTarget; - data << int32(WorldLootObjectInventorySwapSlot); - data << uint32(VisualItemReplacements.size()); - for (uint32 i = 0; i < 19; ++i) - { - data << uint32(PlunderstormItemDisplayID[i]); - } - PersonalTabard->WriteCreate(data, receiver, owner); - NpcAsPlayerInfo->WriteCreate(data, receiver, owner); - for (uint32 i = 0; i < Customizations.size(); ++i) - { - Customizations[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < RandomCustomizations.size(); ++i) - { - RandomCustomizations[i].WriteCreate(data, receiver, owner); - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - { - for (uint32 i = 0; i < QuestSessionQuestLog.size(); ++i) - { - QuestSessionQuestLog[i].WriteCreate(data, receiver, owner); - } - } - for (uint32 i = 0; i < ArenaCooldowns.size(); ++i) - { - ArenaCooldowns[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < VisualItemReplacements.size(); ++i) - { - data << int32(VisualItemReplacements[i]); - } - for (uint32 i = 0; i < 19; ++i) - { - VisibleItems[i].WriteCreate(data, receiver, owner); - } - data.FlushBits(); - data.WriteBits(Name->size(), 6); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - { - data.WriteBit(HasQuestSession); - } - data.WriteBit(HasLevelLink); - data.WriteBits(DeclinedNames.has_value(), 1); - data << *DungeonScore; - data << WorldPackets::SizedString::Data(*Name); - LeaverInfo->WriteCreate(data, receiver, owner); - for (uint32 i = 0; i < 16; ++i) - { - data << VisibleEquipableSpells[i]; - } - for (uint32 i = 0; i < PetNames.size(); ++i) - { - PetNames[i].WriteCreate(data, receiver, owner); - } - if (DeclinedNames.has_value()) - { - DeclinedNames->WriteCreate(data, receiver, owner); - } - data.FlushBits(); -} - -static constexpr void PlayerDataAppendAllowedFieldsMaskForFlag(PlayerData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - allowedMaskForTarget |= std::array{ 0x00000022u, 0xFFF00000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000000Fu, 0x00000000u, 0x00000000u, 0x00000000u }; -} - -void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); -} - -void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) -{ - Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x000FFFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFF0u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000001Fu }); - PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - changesMask &= allowedMaskForTarget; -} - -void PlayerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x000FFFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFF0u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000001Fu }); - PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); -} - -void PlayerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 11); - for (uint32 i = 0; i < 11; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - bool noQuestLogChangesMask = data.WriteBit(IsQuestLogChangesMaskSkipped()); - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(HasQuestSession); - } - if (changesMask[2]) - { - data.WriteBit(HasLevelLink); - } - if (changesMask[3]) - { - if (!ignoreNestedChangesMask) - Customizations.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Customizations.size(), data); - } - if (changesMask[4]) - { - if (!ignoreNestedChangesMask) - RandomCustomizations.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(RandomCustomizations.size(), data); - } - if (changesMask[5]) - { - if (!ignoreNestedChangesMask) - QuestSessionQuestLog.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(QuestSessionQuestLog.size(), data); - } - if (changesMask[6]) - { - if (!ignoreNestedChangesMask) - ArenaCooldowns.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ArenaCooldowns.size(), data); - } - if (changesMask[7]) - { - if (!ignoreNestedChangesMask) - PetNames.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(PetNames.size(), data); - } - if (changesMask[8]) - { - if (!ignoreNestedChangesMask) - VisualItemReplacements.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(VisualItemReplacements.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - for (uint32 i = 0; i < Customizations.size(); ++i) - { - if (Customizations.HasChanged(i) || ignoreNestedChangesMask) - { - Customizations[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[4]) - { - for (uint32 i = 0; i < RandomCustomizations.size(); ++i) - { - if (RandomCustomizations.HasChanged(i) || ignoreNestedChangesMask) - { - RandomCustomizations[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[5]) - { - for (uint32 i = 0; i < QuestSessionQuestLog.size(); ++i) - { - if (QuestSessionQuestLog.HasChanged(i) || ignoreNestedChangesMask) - { - if (noQuestLogChangesMask) - QuestSessionQuestLog[i].WriteCreate(data, receiver, owner); - else - QuestSessionQuestLog[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[6]) - { - for (uint32 i = 0; i < ArenaCooldowns.size(); ++i) - { - if (ArenaCooldowns.HasChanged(i) || ignoreNestedChangesMask) - { - ArenaCooldowns[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[8]) - { - for (uint32 i = 0; i < VisualItemReplacements.size(); ++i) - { - if (VisualItemReplacements.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(VisualItemReplacements[i]); - } - } - } - if (changesMask[7]) - { - for (uint32 i = 0; i < PetNames.size(); ++i) - { - if (PetNames.HasChanged(i) || ignoreNestedChangesMask) - { - PetNames[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[9]) - { - data << *DuelArbiter; - } - if (changesMask[10]) - { - data << *WowAccount; - } - if (changesMask[11]) - { - data << *BnetAccount; - } - if (changesMask[12]) - { - data << uint64(GuildClubMemberID); - } - if (changesMask[13]) - { - data << *LootTargetGUID; - } - if (changesMask[14]) - { - data << uint32(PlayerFlags); - } - if (changesMask[15]) - { - data << uint32(PlayerFlagsEx); - } - if (changesMask[16]) - { - data << uint32(GuildRankID); - } - if (changesMask[17]) - { - data << uint32(GuildDeleteDate); - } - if (changesMask[18]) - { - data << int32(GuildLevel); - } - if (changesMask[19]) - { - data << uint8(NativeSex); - } - if (changesMask[20]) - { - data << uint8(Inebriation); - } - if (changesMask[21]) - { - data << uint8(PvpTitle); - } - if (changesMask[22]) - { - data << uint8(ArenaFaction); - } - if (changesMask[23]) - { - data << uint32(DuelTeam); - } - if (changesMask[24]) - { - data << int32(GuildTimeStamp); - } - if (changesMask[25]) - { - data << int32(PlayerTitle); - } - if (changesMask[26]) - { - data << int32(FakeInebriation); - } - if (changesMask[27]) - { - data << uint32(VirtualPlayerRealm); - } - if (changesMask[28]) - { - data << uint32(CurrentSpecID); - } - if (changesMask[29]) - { - data << int32(CurrentCombatTraitConfigSubTreeID); - } - if (changesMask[30]) - { - data << int32(TaxiMountAnimKitID); - } - if (changesMask[31]) - { - data << uint8(CurrentBattlePetBreedQuality); - } - } - if (changesMask[32]) - { - if (changesMask[33]) - { - data << int32(HonorLevel); - } - if (changesMask[34]) - { - data << int64(LogoutTime); - } - if (changesMask[36]) - { - data << int32(OfferedAdvJournalQuestID); - } - if (changesMask[37]) - { - data << int32(OfferedScriptQuestID); - } - if (changesMask[38]) - { - data << int32(CurrentBattlePetSpeciesID); - } - if (changesMask[39]) - { - CtrOptions->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[40]) - { - data << int32(CovenantID); - } - if (changesMask[41]) - { - data << int32(SoulbindID); - } - if (changesMask[44]) - { - data << *SpectateTarget; - } - if (changesMask[45]) - { - data << int32(WorldLootObjectInventorySwapSlot); - } - if (changesMask[47]) - { - PersonalTabard->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[48]) - { - NpcAsPlayerInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[35]) - { - data.WriteBits(Name->size(), 6); - } - data.WriteBits(DeclinedNames.has_value(), 1); - data.FlushBits(); - if (changesMask[42]) - { - data << *DungeonScore; - } - if (changesMask[35]) - { - data << WorldPackets::SizedString::Data(*Name); - } - if (changesMask[43]) - { - LeaverInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[46]) - { - if (DeclinedNames.has_value()) - { - DeclinedNames->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[49]) - { - for (uint32 i = 0; i < 2; ++i) - { - if (changesMask[50 + i]) - { - data << uint8(PartyType[i]); - } - } - } - if (changesMask[52]) - { - for (uint32 i = 0; i < 175; ++i) - { - if (changesMask[53 + i]) - { - if (noQuestLogChangesMask) - QuestLog[i].WriteCreate(data, receiver, owner); - else - QuestLog[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[248]) - { - for (uint32 i = 0; i < 6; ++i) - { - if (changesMask[249 + i]) - { - data << float(AvgItemLevel[i]); - } - } - } - if (changesMask[255]) - { - for (uint32 i = 0; i < 32; ++i) - { - if (changesMask[256 + i]) - { - ForcedReactions[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[305]) - { - for (uint32 i = 0; i < 19; ++i) - { - if (changesMask[306 + i]) - { - data << uint32(PlunderstormItemDisplayID[i]); - } - } - } - if (changesMask[228]) - { - for (uint32 i = 0; i < 19; ++i) - { - if (changesMask[229 + i]) - { - VisibleItems[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[288]) - { - for (uint32 i = 0; i < 16; ++i) - { - if (changesMask[289 + i]) - { - data << VisibleEquipableSpells[i]; - } - } - } - data.FlushBits(); -} - -void PlayerData::ClearChangesMask() -{ - Base::ClearChangesMask(HasQuestSession); - Base::ClearChangesMask(HasLevelLink); - Base::ClearChangesMask(Customizations); - Base::ClearChangesMask(RandomCustomizations); - Base::ClearChangesMask(QuestSessionQuestLog); - Base::ClearChangesMask(ArenaCooldowns); - Base::ClearChangesMask(VisualItemReplacements); - Base::ClearChangesMask(PetNames); - Base::ClearChangesMask(DuelArbiter); - Base::ClearChangesMask(WowAccount); - Base::ClearChangesMask(BnetAccount); - Base::ClearChangesMask(GuildClubMemberID); - Base::ClearChangesMask(LootTargetGUID); - Base::ClearChangesMask(PlayerFlags); - Base::ClearChangesMask(PlayerFlagsEx); - Base::ClearChangesMask(GuildRankID); - Base::ClearChangesMask(GuildDeleteDate); - Base::ClearChangesMask(GuildLevel); - Base::ClearChangesMask(NativeSex); - Base::ClearChangesMask(Inebriation); - Base::ClearChangesMask(PvpTitle); - Base::ClearChangesMask(ArenaFaction); - Base::ClearChangesMask(DuelTeam); - Base::ClearChangesMask(GuildTimeStamp); - Base::ClearChangesMask(PlayerTitle); - Base::ClearChangesMask(FakeInebriation); - Base::ClearChangesMask(VirtualPlayerRealm); - Base::ClearChangesMask(CurrentSpecID); - Base::ClearChangesMask(CurrentCombatTraitConfigSubTreeID); - Base::ClearChangesMask(TaxiMountAnimKitID); - Base::ClearChangesMask(CurrentBattlePetBreedQuality); - Base::ClearChangesMask(HonorLevel); - Base::ClearChangesMask(LogoutTime); - Base::ClearChangesMask(Name); - Base::ClearChangesMask(OfferedAdvJournalQuestID); - Base::ClearChangesMask(OfferedScriptQuestID); - Base::ClearChangesMask(CurrentBattlePetSpeciesID); - Base::ClearChangesMask(CtrOptions); - Base::ClearChangesMask(CovenantID); - Base::ClearChangesMask(SoulbindID); - Base::ClearChangesMask(DungeonScore); - Base::ClearChangesMask(LeaverInfo); - Base::ClearChangesMask(SpectateTarget); - Base::ClearChangesMask(WorldLootObjectInventorySwapSlot); - Base::ClearChangesMask(DeclinedNames); - Base::ClearChangesMask(PersonalTabard); - Base::ClearChangesMask(NpcAsPlayerInfo); - Base::ClearChangesMask(PartyType); - Base::ClearChangesMask(QuestLog); - Base::ClearChangesMask(VisibleItems); - Base::ClearChangesMask(AvgItemLevel); - Base::ClearChangesMask(ForcedReactions); - Base::ClearChangesMask(VisibleEquipableSpells); - Base::ClearChangesMask(PlunderstormItemDisplayID); - _changesMask.ResetAll(); -} - -void SkillInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - for (uint32 i = 0; i < 300; ++i) - { - data << uint16(SkillLineID[i]); - data << uint16(SkillStep[i]); - data << uint16(SkillRank[i]); - data << uint16(SkillStartingRank[i]); - data << uint16(SkillMaxRank[i]); - data << int16(SkillTempBonus[i]); - data << uint16(SkillPermBonus[i]); - } -} - -void SkillInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - for (uint32 i = 0; i < 2; ++i) - data << uint32(changesMask.GetBlocksMask(i)); - data.WriteBits(changesMask.GetBlocksMask(2), 2); - for (uint32 i = 0; i < 66; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - data.FlushBits(); - if (changesMask[0]) - { - for (uint32 i = 0; i < 300; ++i) - { - if (changesMask[1 + i]) - { - data << uint16(SkillLineID[i]); - } - if (changesMask[301 + i]) - { - data << uint16(SkillStep[i]); - } - if (changesMask[601 + i]) - { - data << uint16(SkillRank[i]); - } - if (changesMask[901 + i]) - { - data << uint16(SkillStartingRank[i]); - } - if (changesMask[1201 + i]) - { - data << uint16(SkillMaxRank[i]); - } - if (changesMask[1501 + i]) - { - data << int16(SkillTempBonus[i]); - } - if (changesMask[1801 + i]) - { - data << uint16(SkillPermBonus[i]); - } - } - } -} - -void SkillInfo::ClearChangesMask() -{ - Base::ClearChangesMask(SkillLineID); - Base::ClearChangesMask(SkillStep); - Base::ClearChangesMask(SkillRank); - Base::ClearChangesMask(SkillStartingRank); - Base::ClearChangesMask(SkillMaxRank); - Base::ClearChangesMask(SkillTempBonus); - Base::ClearChangesMask(SkillPermBonus); - _changesMask.ResetAll(); -} - -void BitVector::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(Values.size()); - for (uint32 i = 0; i < Values.size(); ++i) - { - data << uint64(Values[i]); - } -} - -void BitVector::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 2); - - if (changesMask[0]) - { - if (changesMask[1]) + if (changesMask[0]) { if (!ignoreChangesMask) - Values.WriteUpdateMask(data); + Values.WriteUpdateMask(data, 6); else - WriteCompleteDynamicFieldUpdateMask(Values.size(), data); + WriteCompleteDynamicFieldUpdateMask(Values.size(), data, 6); } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) + data.FlushBits(); + if (changesMask[0]) { for (uint32 i = 0; i < Values.size(); ++i) { if (Values.HasChanged(i) || ignoreChangesMask) { - data << uint64(Values[i]); + Values[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + data.FlushBits(); + } + + void ItemModList::ClearChangesMask() + { + Base::ClearChangesMask(Values); + _changesMask.ResetAll(); + } + + void ArtifactPower::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const + { + data << int16(ArtifactPowerID); + data << uint8(PurchasedRank); + data << uint8(CurrentRankWithBonus); + } + + void ArtifactPower::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const + { + data << int16(ArtifactPowerID); + data << uint8(PurchasedRank); + data << uint8(CurrentRankWithBonus); + } + + bool ArtifactPower::operator==(ArtifactPower const& right) const + { + return ArtifactPowerID == right.ArtifactPowerID + && PurchasedRank == right.PurchasedRank + && CurrentRankWithBonus == right.CurrentRankWithBonus; + } + + void SocketedGem::WriteCreate(ByteBuffer& data, Player const* receiver, Item const* owner) const + { + data << int32(ItemID); + for (uint32 i = 0; i < 16; ++i) + { + data << uint16(BonusListIDs[i]); + } + data << uint8(Context); + } + + void SocketedGem::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Item const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlocksMask(0), 1); + if (changesMask.GetBlock(0)) + data.WriteBits(changesMask.GetBlock(0), 32); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(ItemID); + } + if (changesMask[2]) + { + data << uint8(Context); + } + } + if (changesMask[3]) + { + for (uint32 i = 0; i < 16; ++i) + { + if (changesMask[4 + i]) + { + data << uint16(BonusListIDs[i]); } } } } -} -void BitVector::ClearChangesMask() -{ - Base::ClearChangesMask(Values); - _changesMask.ResetAll(); -} - -void BitVectors::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - for (uint32 i = 0; i < 14; ++i) + void SocketedGem::ClearChangesMask() { - Values[i].WriteCreate(data, receiver, owner); + Base::ClearChangesMask(ItemID); + Base::ClearChangesMask(Context); + Base::ClearChangesMask(BonusListIDs); + _changesMask.ResetAll(); } -} -void BitVectors::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); + void ItemData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Item const* owner) const + { + data << *Owner; + data << *ContainedIn; + data << *Creator; + data << *GiftCreator; + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(StackCount); + data << uint32(Expiration); + for (uint32 i = 0; i < 5; ++i) + { + data << int32(SpellCharges[i]); + } + } + data << uint32(DynamicFlags); + for (uint32 i = 0; i < 13; ++i) + { + Enchantment[i].WriteCreate(data, receiver, owner); + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(Durability); + data << uint32(MaxDurability); + } + data << uint32(CreatePlayedTime); + data << uint8(Context); + data << int64(CreateTime); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint64(ArtifactXP); + data << uint8(ItemAppearanceModID); + } + data << uint32(ArtifactPowers.size()); + data << uint32(Gems.size()); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(ZoneFlags); + } + data << *ItemBonusKey; + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint16(DEBUGItemLevel); + } + for (uint32 i = 0; i < ArtifactPowers.size(); ++i) + { + ArtifactPowers[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < Gems.size(); ++i) + { + Gems[i].WriteCreate(data, receiver, owner); + } + Modifiers->WriteCreate(data, receiver, owner); + } - data.WriteBits(changesMask.GetBlocksMask(0), 1); - if (changesMask.GetBlock(0)) - data.WriteBits(changesMask.GetBlock(0), 32); + static constexpr void ItemDataAppendAllowedFieldsMaskForFlag(ItemData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array{ 0x07F58D80u, 0x00000000u }; + } - data.FlushBits(); - if (changesMask[0]) + void ItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + } + + void ItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) + { + Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); + ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; + } + + void ItemData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Item const* owner) const + { + Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu }); + ItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); + } + + void ItemData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Item const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 2); + for (uint32 i = 0; i < 2; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreNestedChangesMask) + ArtifactPowers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ArtifactPowers.size(), data); + } + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + Gems.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Gems.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < ArtifactPowers.size(); ++i) + { + if (ArtifactPowers.HasChanged(i) || ignoreNestedChangesMask) + { + ArtifactPowers[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < Gems.size(); ++i) + { + if (Gems.HasChanged(i) || ignoreNestedChangesMask) + { + Gems[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[3]) + { + data << *Owner; + } + if (changesMask[4]) + { + data << *ContainedIn; + } + if (changesMask[5]) + { + data << *Creator; + } + if (changesMask[6]) + { + data << *GiftCreator; + } + if (changesMask[7]) + { + data << uint32(StackCount); + } + if (changesMask[8]) + { + data << uint32(Expiration); + } + if (changesMask[9]) + { + data << uint32(DynamicFlags); + } + if (changesMask[10]) + { + data << uint32(Durability); + } + if (changesMask[11]) + { + data << uint32(MaxDurability); + } + if (changesMask[12]) + { + data << uint32(CreatePlayedTime); + } + if (changesMask[13]) + { + data << uint8(Context); + } + if (changesMask[14]) + { + data << int64(CreateTime); + } + if (changesMask[15]) + { + data << uint64(ArtifactXP); + } + if (changesMask[16]) + { + data << uint8(ItemAppearanceModID); + } + if (changesMask[18]) + { + data << uint32(ZoneFlags); + } + if (changesMask[19]) + { + data << *ItemBonusKey; + } + if (changesMask[20]) + { + data << uint16(DEBUGItemLevel); + } + if (changesMask[17]) + { + Modifiers->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[21]) + { + for (uint32 i = 0; i < 5; ++i) + { + if (changesMask[22 + i]) + { + data << int32(SpellCharges[i]); + } + } + } + if (changesMask[27]) + { + for (uint32 i = 0; i < 13; ++i) + { + if (changesMask[28 + i]) + { + Enchantment[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + + void ItemData::ClearChangesMask() + { + Base::ClearChangesMask(ArtifactPowers); + Base::ClearChangesMask(Gems); + Base::ClearChangesMask(Owner); + Base::ClearChangesMask(ContainedIn); + Base::ClearChangesMask(Creator); + Base::ClearChangesMask(GiftCreator); + Base::ClearChangesMask(StackCount); + Base::ClearChangesMask(Expiration); + Base::ClearChangesMask(DynamicFlags); + Base::ClearChangesMask(Durability); + Base::ClearChangesMask(MaxDurability); + Base::ClearChangesMask(CreatePlayedTime); + Base::ClearChangesMask(Context); + Base::ClearChangesMask(CreateTime); + Base::ClearChangesMask(ArtifactXP); + Base::ClearChangesMask(ItemAppearanceModID); + Base::ClearChangesMask(Modifiers); + Base::ClearChangesMask(ZoneFlags); + Base::ClearChangesMask(ItemBonusKey); + Base::ClearChangesMask(DEBUGItemLevel); + Base::ClearChangesMask(SpellCharges); + Base::ClearChangesMask(Enchantment); + _changesMask.ResetAll(); + } + + void ContainerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Bag const* owner) const + { + for (uint32 i = 0; i < 98; ++i) + { + data << Slots[i]; + } + data << uint32(NumSlots); + } + + void ContainerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Bag const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void ContainerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Bag const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 4); + for (uint32 i = 0; i < 4; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(NumSlots); + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < 98; ++i) + { + if (changesMask[3 + i]) + { + data << Slots[i]; + } + } + } + } + + void ContainerData::ClearChangesMask() + { + Base::ClearChangesMask(NumSlots); + Base::ClearChangesMask(Slots); + _changesMask.ResetAll(); + } + + void AzeriteEmpoweredItemData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteEmpoweredItem const* owner) const + { + for (uint32 i = 0; i < 5; ++i) + { + data << int32(Selections[i]); + } + } + + void AzeriteEmpoweredItemData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteEmpoweredItem const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void AzeriteEmpoweredItemData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AzeriteEmpoweredItem const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 1); + if (changesMask.GetBlock(0)) + data.WriteBits(changesMask.GetBlock(0), 32); + + data.FlushBits(); + if (changesMask[0]) + { + for (uint32 i = 0; i < 5; ++i) + { + if (changesMask[1 + i]) + { + data << int32(Selections[i]); + } + } + } + } + + void AzeriteEmpoweredItemData::ClearChangesMask() + { + Base::ClearChangesMask(Selections); + _changesMask.ResetAll(); + } + + void UnlockedAzeriteEssence::WriteCreate(ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const + { + data << uint32(AzeriteEssenceID); + data << uint32(Rank); + } + + void UnlockedAzeriteEssence::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const + { + data << uint32(AzeriteEssenceID); + data << uint32(Rank); + } + + bool UnlockedAzeriteEssence::operator==(UnlockedAzeriteEssence const& right) const + { + return AzeriteEssenceID == right.AzeriteEssenceID + && Rank == right.Rank; + } + + void SelectedAzeriteEssences::WriteCreate(ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const + { + for (uint32 i = 0; i < 4; ++i) + { + data << uint32(AzeriteEssenceID[i]); + } + data << uint32(SpecializationID); + data.WriteBit(Enabled); + data.FlushBits(); + } + + void SelectedAzeriteEssences::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlocksMask(0), 1); + if (changesMask.GetBlock(0)) + data.WriteBits(changesMask.GetBlock(0), 32); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(Enabled); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + data << uint32(SpecializationID); + } + } + if (changesMask[3]) + { + for (uint32 i = 0; i < 4; ++i) + { + if (changesMask[4 + i]) + { + data << uint32(AzeriteEssenceID[i]); + } + } + } + data.FlushBits(); + } + + void SelectedAzeriteEssences::ClearChangesMask() + { + Base::ClearChangesMask(Enabled); + Base::ClearChangesMask(SpecializationID); + Base::ClearChangesMask(AzeriteEssenceID); + _changesMask.ResetAll(); + } + + void AzeriteItemData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint64(Xp); + data << uint32(Level); + data << uint32(AuraLevel); + data << uint32(KnowledgeLevel); + data << int32(DEBUGknowledgeWeek); + } + data << uint32(UnlockedEssences.size()); + data << uint32(SelectedEssences.size()); + data << uint32(UnlockedEssenceMilestones.size()); + for (uint32 i = 0; i < UnlockedEssences.size(); ++i) + { + UnlockedEssences[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < UnlockedEssenceMilestones.size(); ++i) + { + data << uint32(UnlockedEssenceMilestones[i]); + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data.WriteBit(Enabled); + } + for (uint32 i = 0; i < SelectedEssences.size(); ++i) + { + SelectedEssences[i].WriteCreate(data, receiver, owner); + } + data.FlushBits(); + } + + static constexpr void AzeriteItemDataAppendAllowedFieldsMaskForFlag(AzeriteItemData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array{ 0x000003E2u }; + } + + void AzeriteItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + } + + void AzeriteItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) + { + Mask allowedMaskForTarget({ 0x0000001Du }); + AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; + } + + void AzeriteItemData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner) const + { + Mask allowedMaskForTarget({ 0x0000001Du }); + AzeriteItemDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); + } + + void AzeriteItemData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AzeriteItem const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 10); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(Enabled); + } + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + UnlockedEssences.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(UnlockedEssences.size(), data); + } + if (changesMask[3]) + { + if (!ignoreNestedChangesMask) + SelectedEssences.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SelectedEssences.size(), data); + } + if (changesMask[4]) + { + if (!ignoreNestedChangesMask) + UnlockedEssenceMilestones.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(UnlockedEssenceMilestones.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + for (uint32 i = 0; i < UnlockedEssences.size(); ++i) + { + if (UnlockedEssences.HasChanged(i) || ignoreNestedChangesMask) + { + UnlockedEssences[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[4]) + { + for (uint32 i = 0; i < UnlockedEssenceMilestones.size(); ++i) + { + if (UnlockedEssenceMilestones.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(UnlockedEssenceMilestones[i]); + } + } + } + if (changesMask[3]) + { + for (uint32 i = 0; i < SelectedEssences.size(); ++i) + { + if (SelectedEssences.HasChanged(i) || ignoreNestedChangesMask) + { + SelectedEssences[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[5]) + { + data << uint64(Xp); + } + if (changesMask[6]) + { + data << uint32(Level); + } + if (changesMask[7]) + { + data << uint32(AuraLevel); + } + if (changesMask[8]) + { + data << uint32(KnowledgeLevel); + } + if (changesMask[9]) + { + data << int32(DEBUGknowledgeWeek); + } + } + data.FlushBits(); + } + + void AzeriteItemData::ClearChangesMask() + { + Base::ClearChangesMask(Enabled); + Base::ClearChangesMask(UnlockedEssences); + Base::ClearChangesMask(UnlockedEssenceMilestones); + Base::ClearChangesMask(SelectedEssences); + Base::ClearChangesMask(Xp); + Base::ClearChangesMask(Level); + Base::ClearChangesMask(AuraLevel); + Base::ClearChangesMask(KnowledgeLevel); + Base::ClearChangesMask(DEBUGknowledgeWeek); + _changesMask.ResetAll(); + } + + void SpellCastVisual::WriteCreate(ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << int32(SpellXSpellVisualID); + data << int32(ScriptVisualID); + } + + void SpellCastVisual::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << int32(SpellXSpellVisualID); + data << int32(ScriptVisualID); + } + + bool SpellCastVisual::operator==(SpellCastVisual const& right) const + { + return SpellXSpellVisualID == right.SpellXSpellVisualID + && ScriptVisualID == right.ScriptVisualID; + } + + void UnitChannel::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + data << int32(SpellID); + SpellVisual.WriteCreate(data, receiver, owner); + data << uint32(StartTimeMs); + data << uint32(Duration); + } + + void UnitChannel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + data << int32(SpellID); + SpellVisual.WriteUpdate(ignoreChangesMask, data, receiver, owner); + data << uint32(StartTimeMs); + data << uint32(Duration); + } + + bool UnitChannel::operator==(UnitChannel const& right) const + { + return SpellID == right.SpellID + && SpellVisual == right.SpellVisual + && StartTimeMs == right.StartTimeMs + && Duration == right.Duration; + } + + void VisibleItem::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + data << int32(ItemID); + data << int32(SecondaryItemModifiedAppearanceID); + data << int32(ConditionalItemAppearanceID); + data << uint16(ItemAppearanceModID); + data << uint16(ItemVisual); + data << uint32(ItemModifiedAppearanceID); + data << uint8(Field_18); + data.WriteBit(HasTransmog); + data.WriteBit(HasIllusion); + data.FlushBits(); + } + + void VisibleItem::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 10); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(HasTransmog); + } + if (changesMask[2]) + { + data.WriteBit(HasIllusion); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + data << int32(ItemID); + } + if (changesMask[4]) + { + data << int32(SecondaryItemModifiedAppearanceID); + } + if (changesMask[5]) + { + data << int32(ConditionalItemAppearanceID); + } + if (changesMask[6]) + { + data << uint16(ItemAppearanceModID); + } + if (changesMask[7]) + { + data << uint16(ItemVisual); + } + if (changesMask[8]) + { + data << uint32(ItemModifiedAppearanceID); + } + if (changesMask[9]) + { + data << uint8(Field_18); + } + } + data.FlushBits(); + } + + void VisibleItem::ClearChangesMask() + { + Base::ClearChangesMask(HasTransmog); + Base::ClearChangesMask(HasIllusion); + Base::ClearChangesMask(ItemID); + Base::ClearChangesMask(SecondaryItemModifiedAppearanceID); + Base::ClearChangesMask(ConditionalItemAppearanceID); + Base::ClearChangesMask(ItemAppearanceModID); + Base::ClearChangesMask(ItemVisual); + Base::ClearChangesMask(ItemModifiedAppearanceID); + Base::ClearChangesMask(Field_18); + _changesMask.ResetAll(); + } + + void PassiveSpellHistory::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + data << int32(SpellID); + data << int32(AuraSpellID); + } + + void PassiveSpellHistory::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + data << int32(SpellID); + data << int32(AuraSpellID); + } + + bool PassiveSpellHistory::operator==(PassiveSpellHistory const& right) const + { + return SpellID == right.SpellID + && AuraSpellID == right.AuraSpellID; + } + + void UnitAssistActionData::WriteCreate(ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + data << uint8(Type); + data << uint32(VirtualRealmAddress); + data.WriteBits(PlayerName->size(), 6); + data.FlushBits(); + data << WorldPackets::SizedString::Data(*PlayerName); + } + + void UnitAssistActionData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint8(Type); + } + if (changesMask[3]) + { + data << uint32(VirtualRealmAddress); + } + if (changesMask[2]) + { + data.WriteBits(PlayerName->size(), 6); + data.FlushBits(); + data << WorldPackets::SizedString::Data(*PlayerName); + } + } + } + + void UnitAssistActionData::ClearChangesMask() + { + Base::ClearChangesMask(Type); + Base::ClearChangesMask(PlayerName); + Base::ClearChangesMask(VirtualRealmAddress); + _changesMask.ResetAll(); + } + + void UnitData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + ViewerDependentValue::value_type stateWorldEffectIDs = {}; + + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); + data << uint32(stateWorldEffectIDs->size()); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << int32(SpellOverrideNameID); + for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) + { + data << uint32((*stateWorldEffectIDs)[i]); + } + data << *Charm; + data << *Summon; + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << *Critter; + } + data << *CharmedBy; + data << *SummonedBy; + data << *CreatedBy; + data << *DemonCreator; + data << *LookAtControllerTarget; + data << *Target; + data << *BattlePetCompanionGUID; + data << uint64(BattlePetDBID); + ChannelData->WriteCreate(data, receiver, owner); + data << int8(SpellEmpowerStage); + data << uint32(SummonedByHomeRealm); + data << uint8(Race); + data << uint8(ClassId); + data << uint8(PlayerClassId); + data << uint8(Sex); + data << uint8(CreatureType); + data << uint8(DisplayPower); + data << uint32(OverrideDisplayPowerID); + data << int64(Health); + for (uint32 i = 0; i < 10; ++i) + { + data << int32(Power[i]); + data << int32(MaxPower[i]); + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::UnitAll)) + { + for (uint32 i = 0; i < 10; ++i) + { + data << float(PowerRegenFlatModifier[i]); + data << float(PowerRegenInterruptedFlatModifier[i]); + } + } + data << int64(MaxHealth); + data << int32(Level); + data << int32(EffectiveLevel); + data << int32(ContentTuningID); + data << int32(ScalingLevelMin); + data << int32(ScalingLevelMax); + data << int32(ScalingLevelDelta); + data << uint8(ScalingFactionGroup); + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + for (uint32 i = 0; i < 2; ++i) + { + data << uint32(AttackRoundBaseTime[i]); + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(RangedAttackRoundBaseTime); + } + data << float(BoundingRadius); + data << float(CombatReach); + data << float(DisplayScale); + data << int32(CreatureFamily); + data << uint8(OverrideCreatureType); + data << int32(NativeDisplayID); + data << float(NativeXDisplayScale); + data << int32(MountDisplayID); + data << int32(CosmeticMountDisplayID); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::Empath)) + { + data << float(MinDamage); + data << float(MaxDamage); + data << float(MinOffHandDamage); + data << float(MaxOffHandDamage); + } + data << uint8(StandState); + data << uint8(PetTalentPoints); + data << uint8(VisFlags); + data << uint8(AnimTier); + data << uint32(PetNumber); + data << uint32(PetNameTimestamp); + data << uint32(PetExperience); + data << uint32(PetNextLevelExperience); + data << float(ModCastingSpeed); + data << float(ModCastingSpeedNeg); + data << float(ModSpellHaste); + data << float(ModHaste); + data << float(ModRangedHaste); + data << float(ModHasteRegen); + data << float(ModTimeRate); + data << int32(CreatedBySpell); + data << int32(EmoteState); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + for (uint32 i = 0; i < 5; ++i) + { + data << int32(Stats[i]); + data << int32(StatPosBuff[i]); + data << int32(StatNegBuff[i]); + data << int32(StatSupportBuff[i]); + } + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::Empath)) + { + for (uint32 i = 0; i < 7; ++i) + { + data << int32(Resistances[i]); + } + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + for (uint32 i = 0; i < 7; ++i) + { + data << int32(BonusResistanceMods[i]); + data << int32(ManaCostModifier[i]); + } + } + data << int32(BaseMana); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << int32(BaseHealth); + } + data << uint8(SheatheState); + data << uint8(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint8(PetFlags); + data << uint8(ShapeshiftForm); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << int32(AttackPower); + data << int32(AttackPowerModPos); + data << int32(AttackPowerModNeg); + data << float(AttackPowerMultiplier); + data << int32(AttackPowerModSupport); + data << int32(RangedAttackPower); + data << int32(RangedAttackPowerModPos); + data << int32(RangedAttackPowerModNeg); + data << float(RangedAttackPowerMultiplier); + data << int32(RangedAttackPowerModSupport); + data << int32(MainHandWeaponAttackPower); + data << int32(OffHandWeaponAttackPower); + data << int32(RangedWeaponAttackPower); + data << int32(SetAttackSpeedAura); + data << float(Lifesteal); + data << float(MinRangedDamage); + data << float(MaxRangedDamage); + data << float(ManaCostMultiplier); + } + data << float(MaxHealthModifier); + data << float(HoverHeight); + data << int32(MinItemLevelCutoff); + data << int32(MinItemLevel); + data << int32(MaxItemLevel); + data << int32(AzeriteItemLevel); + data << int32(WildBattlePetLevel); + data << int32(BattlePetCompanionExperience); + data << uint32(BattlePetCompanionNameTimestamp); + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << int32(ScaleDuration); + data << int32(LooksLikeMountID); + data << int32(LooksLikeCreatureID); + data << int32(LookAtControllerID); + data << int32(PerksVendorItemID); + data << int32(TaxiNodesID); + data << *GuildGUID; + data << uint32(PassiveSpells.size()); + data << uint32(WorldEffects.size()); + data << uint32(ChannelObjects.size()); + data << int32(FlightCapabilityID); + data << float(GlideEventSpeedDivisor); + data << int32(DriveCapabilityID); + data << int32(MaxHealthModifierFlatNeg); + data << int32(MaxHealthModifierFlatPos); + data << uint32(SilencedSchoolMask); + data << uint32(CurrentAreaID); + data << float(NameplateDistanceMod); + data << float(AutoAttackRangeMod); + data << *NameplateAttachToGUID; + for (uint32 i = 0; i < PassiveSpells.size(); ++i) + { + PassiveSpells[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < WorldEffects.size(); ++i) + { + data << int32(WorldEffects[i]); + } + for (uint32 i = 0; i < ChannelObjects.size(); ++i) + { + data << ChannelObjects[i]; + } + for (uint32 i = 0; i < 3; ++i) + { + VirtualItems[i].WriteCreate(data, receiver, owner); + } + data.FlushBits(); + data.WriteBit(Field_314); + data.WriteBits(AssistActionData.has_value(), 1); + if (AssistActionData.has_value()) + { + AssistActionData->WriteCreate(data, receiver, owner); + } + data.FlushBits(); + } + + static constexpr void UnitDataAppendAllowedFieldsMaskForFlag(UnitData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array{ 0x00010000u, 0xE0080000u, 0xFE100002u, 0x00000FFEu, 0xC0000200u, 0xFE03FFFFu, 0xFFFFFFFFu, 0x0000000Fu }; + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) + allowedMaskForTarget |= std::array{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xC0000200u, 0x0003FFFFu, 0x00000000u, 0x00000000u }; + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) + allowedMaskForTarget |= std::array{ 0x00000000u, 0xE0000000u, 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u, 0x003FC000u, 0x00000000u }; + } + + void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + } + + void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) + { + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x1FF7FFFFu, 0x01EFFFFDu, 0xFFFFF001u, 0x3FFFFFFFu, 0x01FC0000u, 0x00000000u, 0x00000000u }); + UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; + } + + void UnitData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Unit const* owner) const + { + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x1FF7FFFFu, 0x01EFFFFDu, 0xFFFFF001u, 0x3FFFFFFFu, 0x01FC0000u, 0x00000000u, 0x00000000u }); + UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); + } + + void UnitData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Unit const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 8); + for (uint32 i = 0; i < 8; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + ViewerDependentValue::value_type stateWorldEffectIDs = {}; + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(Field_314); + } + if (changesMask[2]) + { + stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); + data.WriteBits(stateWorldEffectIDs->size(), 32); + for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) + { + data << uint32((*stateWorldEffectIDs)[i]); + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + if (!ignoreNestedChangesMask) + PassiveSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(PassiveSpells.size(), data); + } + if (changesMask[4]) + { + if (!ignoreNestedChangesMask) + WorldEffects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WorldEffects.size(), data); + } + if (changesMask[5]) + { + if (!ignoreNestedChangesMask) + ChannelObjects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ChannelObjects.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + for (uint32 i = 0; i < PassiveSpells.size(); ++i) + { + if (PassiveSpells.HasChanged(i) || ignoreNestedChangesMask) + { + PassiveSpells[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[4]) + { + for (uint32 i = 0; i < WorldEffects.size(); ++i) + { + if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(WorldEffects[i]); + } + } + } + if (changesMask[5]) + { + for (uint32 i = 0; i < ChannelObjects.size(); ++i) + { + if (ChannelObjects.HasChanged(i) || ignoreNestedChangesMask) + { + data << ChannelObjects[i]; + } + } + } + if (changesMask[6]) + { + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[7]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[8]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[9]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[10]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[11]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[12]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[13]) + { + data << int32(SpellOverrideNameID); + } + if (changesMask[14]) + { + data << *Charm; + } + if (changesMask[15]) + { + data << *Summon; + } + if (changesMask[16]) + { + data << *Critter; + } + if (changesMask[17]) + { + data << *CharmedBy; + } + if (changesMask[18]) + { + data << *SummonedBy; + } + if (changesMask[19]) + { + data << *CreatedBy; + } + if (changesMask[20]) + { + data << *DemonCreator; + } + if (changesMask[21]) + { + data << *LookAtControllerTarget; + } + if (changesMask[22]) + { + data << *Target; + } + if (changesMask[23]) + { + data << *BattlePetCompanionGUID; + } + if (changesMask[24]) + { + data << uint64(BattlePetDBID); + } + if (changesMask[25]) + { + ChannelData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[26]) + { + data << int8(SpellEmpowerStage); + } + if (changesMask[27]) + { + data << uint32(SummonedByHomeRealm); + } + if (changesMask[28]) + { + data << uint8(Race); + } + if (changesMask[29]) + { + data << uint8(ClassId); + } + if (changesMask[30]) + { + data << uint8(PlayerClassId); + } + if (changesMask[31]) + { + data << uint8(Sex); + } + } + if (changesMask[32]) + { + if (changesMask[33]) + { + data << uint8(CreatureType); + } + if (changesMask[34]) + { + data << uint8(DisplayPower); + } + if (changesMask[35]) + { + data << uint32(OverrideDisplayPowerID); + } + if (changesMask[36]) + { + data << int64(Health); + } + if (changesMask[37]) + { + data << int64(MaxHealth); + } + if (changesMask[38]) + { + data << int32(Level); + } + if (changesMask[39]) + { + data << int32(EffectiveLevel); + } + if (changesMask[40]) + { + data << int32(ContentTuningID); + } + if (changesMask[41]) + { + data << int32(ScalingLevelMin); + } + if (changesMask[42]) + { + data << int32(ScalingLevelMax); + } + if (changesMask[43]) + { + data << int32(ScalingLevelDelta); + } + if (changesMask[44]) + { + data << uint8(ScalingFactionGroup); + } + if (changesMask[45]) + { + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[46]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[47]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[48]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[49]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[50]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[51]) + { + data << uint32(RangedAttackRoundBaseTime); + } + if (changesMask[52]) + { + data << float(BoundingRadius); + } + if (changesMask[53]) + { + data << float(CombatReach); + } + if (changesMask[54]) + { + data << float(DisplayScale); + } + if (changesMask[55]) + { + data << int32(CreatureFamily); + } + if (changesMask[56]) + { + data << uint8(OverrideCreatureType); + } + if (changesMask[57]) + { + data << int32(NativeDisplayID); + } + if (changesMask[58]) + { + data << float(NativeXDisplayScale); + } + if (changesMask[59]) + { + data << int32(MountDisplayID); + } + if (changesMask[60]) + { + data << int32(CosmeticMountDisplayID); + } + if (changesMask[61]) + { + data << float(MinDamage); + } + if (changesMask[62]) + { + data << float(MaxDamage); + } + if (changesMask[63]) + { + data << float(MinOffHandDamage); + } + } + if (changesMask[64]) + { + if (changesMask[65]) + { + data << float(MaxOffHandDamage); + } + if (changesMask[66]) + { + data << uint8(StandState); + } + if (changesMask[67]) + { + data << uint8(PetTalentPoints); + } + if (changesMask[68]) + { + data << uint8(VisFlags); + } + if (changesMask[69]) + { + data << uint8(AnimTier); + } + if (changesMask[70]) + { + data << uint32(PetNumber); + } + if (changesMask[71]) + { + data << uint32(PetNameTimestamp); + } + if (changesMask[72]) + { + data << uint32(PetExperience); + } + if (changesMask[73]) + { + data << uint32(PetNextLevelExperience); + } + if (changesMask[74]) + { + data << float(ModCastingSpeed); + } + if (changesMask[75]) + { + data << float(ModCastingSpeedNeg); + } + if (changesMask[76]) + { + data << float(ModSpellHaste); + } + if (changesMask[77]) + { + data << float(ModHaste); + } + if (changesMask[78]) + { + data << float(ModRangedHaste); + } + if (changesMask[79]) + { + data << float(ModHasteRegen); + } + if (changesMask[80]) + { + data << float(ModTimeRate); + } + if (changesMask[81]) + { + data << int32(CreatedBySpell); + } + if (changesMask[82]) + { + data << int32(EmoteState); + } + if (changesMask[83]) + { + data << int32(BaseMana); + } + if (changesMask[84]) + { + data << int32(BaseHealth); + } + if (changesMask[85]) + { + data << uint8(SheatheState); + } + if (changesMask[86]) + { + data << uint8(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[87]) + { + data << uint8(PetFlags); + } + if (changesMask[88]) + { + data << uint8(ShapeshiftForm); + } + if (changesMask[89]) + { + data << int32(AttackPower); + } + if (changesMask[90]) + { + data << int32(AttackPowerModPos); + } + if (changesMask[91]) + { + data << int32(AttackPowerModNeg); + } + if (changesMask[92]) + { + data << float(AttackPowerMultiplier); + } + if (changesMask[93]) + { + data << int32(AttackPowerModSupport); + } + if (changesMask[94]) + { + data << int32(RangedAttackPower); + } + if (changesMask[95]) + { + data << int32(RangedAttackPowerModPos); + } + } + if (changesMask[96]) + { + if (changesMask[97]) + { + data << int32(RangedAttackPowerModNeg); + } + if (changesMask[98]) + { + data << float(RangedAttackPowerMultiplier); + } + if (changesMask[99]) + { + data << int32(RangedAttackPowerModSupport); + } + if (changesMask[100]) + { + data << int32(MainHandWeaponAttackPower); + } + if (changesMask[101]) + { + data << int32(OffHandWeaponAttackPower); + } + if (changesMask[102]) + { + data << int32(RangedWeaponAttackPower); + } + if (changesMask[103]) + { + data << int32(SetAttackSpeedAura); + } + if (changesMask[104]) + { + data << float(Lifesteal); + } + if (changesMask[105]) + { + data << float(MinRangedDamage); + } + if (changesMask[106]) + { + data << float(MaxRangedDamage); + } + if (changesMask[107]) + { + data << float(ManaCostMultiplier); + } + if (changesMask[108]) + { + data << float(MaxHealthModifier); + } + if (changesMask[109]) + { + data << float(HoverHeight); + } + if (changesMask[110]) + { + data << int32(MinItemLevelCutoff); + } + if (changesMask[111]) + { + data << int32(MinItemLevel); + } + if (changesMask[112]) + { + data << int32(MaxItemLevel); + } + if (changesMask[113]) + { + data << int32(AzeriteItemLevel); + } + if (changesMask[114]) + { + data << int32(WildBattlePetLevel); + } + if (changesMask[115]) + { + data << int32(BattlePetCompanionExperience); + } + if (changesMask[116]) + { + data << uint32(BattlePetCompanionNameTimestamp); + } + if (changesMask[117]) + { + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[118]) + { + data << int32(ScaleDuration); + } + if (changesMask[119]) + { + data << int32(LooksLikeMountID); + } + if (changesMask[120]) + { + data << int32(LooksLikeCreatureID); + } + if (changesMask[121]) + { + data << int32(LookAtControllerID); + } + if (changesMask[122]) + { + data << int32(PerksVendorItemID); + } + if (changesMask[123]) + { + data << int32(TaxiNodesID); + } + if (changesMask[124]) + { + data << *GuildGUID; + } + if (changesMask[125]) + { + data << int32(FlightCapabilityID); + } + if (changesMask[126]) + { + data << float(GlideEventSpeedDivisor); + } + if (changesMask[127]) + { + data << int32(DriveCapabilityID); + } + } + if (changesMask[128]) + { + if (changesMask[129]) + { + data << int32(MaxHealthModifierFlatNeg); + } + if (changesMask[130]) + { + data << int32(MaxHealthModifierFlatPos); + } + if (changesMask[131]) + { + data << uint32(SilencedSchoolMask); + } + if (changesMask[132]) + { + data << uint32(CurrentAreaID); + } + if (changesMask[133]) + { + data << float(NameplateDistanceMod); + } + if (changesMask[134]) + { + data << float(AutoAttackRangeMod); + } + if (changesMask[135]) + { + data << *NameplateAttachToGUID; + } + data.WriteBits(AssistActionData.has_value(), 1); + data.FlushBits(); + if (changesMask[136]) + { + if (AssistActionData.has_value()) + { + AssistActionData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[137]) + { + for (uint32 i = 0; i < 10; ++i) + { + if (changesMask[138 + i]) + { + data << int32(Power[i]); + } + if (changesMask[148 + i]) + { + data << int32(MaxPower[i]); + } + if (changesMask[158 + i]) + { + data << float(PowerRegenFlatModifier[i]); + } + if (changesMask[168 + i]) + { + data << float(PowerRegenInterruptedFlatModifier[i]); + } + } + } + if (changesMask[182]) + { + for (uint32 i = 0; i < 2; ++i) + { + if (changesMask[183 + i]) + { + data << uint32(AttackRoundBaseTime[i]); + } + } + } + if (changesMask[185]) + { + for (uint32 i = 0; i < 5; ++i) + { + if (changesMask[186 + i]) + { + data << int32(Stats[i]); + } + if (changesMask[191 + i]) + { + data << int32(StatPosBuff[i]); + } + if (changesMask[196 + i]) + { + data << int32(StatNegBuff[i]); + } + if (changesMask[201 + i]) + { + data << int32(StatSupportBuff[i]); + } + } + } + if (changesMask[206]) + { + for (uint32 i = 0; i < 7; ++i) + { + if (changesMask[207 + i]) + { + data << int32(Resistances[i]); + } + if (changesMask[214 + i]) + { + data << int32(BonusResistanceMods[i]); + } + if (changesMask[221 + i]) + { + data << int32(ManaCostModifier[i]); + } + } + } + if (changesMask[178]) + { + for (uint32 i = 0; i < 3; ++i) + { + if (changesMask[179 + i]) + { + VirtualItems[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + data.FlushBits(); + } + + void UnitData::ClearChangesMask() + { + Base::ClearChangesMask(Field_314); + Base::ClearChangesMask(StateWorldEffectIDs); + Base::ClearChangesMask(PassiveSpells); + Base::ClearChangesMask(WorldEffects); + Base::ClearChangesMask(ChannelObjects); + Base::ClearChangesMask(DisplayID); + Base::ClearChangesMask(NpcFlags); + Base::ClearChangesMask(NpcFlags2); + Base::ClearChangesMask(StateSpellVisualID); + Base::ClearChangesMask(StateAnimID); + Base::ClearChangesMask(StateAnimKitID); + Base::ClearChangesMask(StateWorldEffectsQuestObjectiveID); + Base::ClearChangesMask(SpellOverrideNameID); + Base::ClearChangesMask(Charm); + Base::ClearChangesMask(Summon); + Base::ClearChangesMask(Critter); + Base::ClearChangesMask(CharmedBy); + Base::ClearChangesMask(SummonedBy); + Base::ClearChangesMask(CreatedBy); + Base::ClearChangesMask(DemonCreator); + Base::ClearChangesMask(LookAtControllerTarget); + Base::ClearChangesMask(Target); + Base::ClearChangesMask(BattlePetCompanionGUID); + Base::ClearChangesMask(BattlePetDBID); + Base::ClearChangesMask(ChannelData); + Base::ClearChangesMask(SpellEmpowerStage); + Base::ClearChangesMask(SummonedByHomeRealm); + Base::ClearChangesMask(Race); + Base::ClearChangesMask(ClassId); + Base::ClearChangesMask(PlayerClassId); + Base::ClearChangesMask(Sex); + Base::ClearChangesMask(CreatureType); + Base::ClearChangesMask(DisplayPower); + Base::ClearChangesMask(OverrideDisplayPowerID); + Base::ClearChangesMask(Health); + Base::ClearChangesMask(MaxHealth); + Base::ClearChangesMask(Level); + Base::ClearChangesMask(EffectiveLevel); + Base::ClearChangesMask(ContentTuningID); + Base::ClearChangesMask(ScalingLevelMin); + Base::ClearChangesMask(ScalingLevelMax); + Base::ClearChangesMask(ScalingLevelDelta); + Base::ClearChangesMask(ScalingFactionGroup); + Base::ClearChangesMask(FactionTemplate); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(Flags2); + Base::ClearChangesMask(Flags3); + Base::ClearChangesMask(Flags4); + Base::ClearChangesMask(AuraState); + Base::ClearChangesMask(RangedAttackRoundBaseTime); + Base::ClearChangesMask(BoundingRadius); + Base::ClearChangesMask(CombatReach); + Base::ClearChangesMask(DisplayScale); + Base::ClearChangesMask(CreatureFamily); + Base::ClearChangesMask(OverrideCreatureType); + Base::ClearChangesMask(NativeDisplayID); + Base::ClearChangesMask(NativeXDisplayScale); + Base::ClearChangesMask(MountDisplayID); + Base::ClearChangesMask(CosmeticMountDisplayID); + Base::ClearChangesMask(MinDamage); + Base::ClearChangesMask(MaxDamage); + Base::ClearChangesMask(MinOffHandDamage); + Base::ClearChangesMask(MaxOffHandDamage); + Base::ClearChangesMask(StandState); + Base::ClearChangesMask(PetTalentPoints); + Base::ClearChangesMask(VisFlags); + Base::ClearChangesMask(AnimTier); + Base::ClearChangesMask(PetNumber); + Base::ClearChangesMask(PetNameTimestamp); + Base::ClearChangesMask(PetExperience); + Base::ClearChangesMask(PetNextLevelExperience); + Base::ClearChangesMask(ModCastingSpeed); + Base::ClearChangesMask(ModCastingSpeedNeg); + Base::ClearChangesMask(ModSpellHaste); + Base::ClearChangesMask(ModHaste); + Base::ClearChangesMask(ModRangedHaste); + Base::ClearChangesMask(ModHasteRegen); + Base::ClearChangesMask(ModTimeRate); + Base::ClearChangesMask(CreatedBySpell); + Base::ClearChangesMask(EmoteState); + Base::ClearChangesMask(BaseMana); + Base::ClearChangesMask(BaseHealth); + Base::ClearChangesMask(SheatheState); + Base::ClearChangesMask(PvpFlags); + Base::ClearChangesMask(PetFlags); + Base::ClearChangesMask(ShapeshiftForm); + Base::ClearChangesMask(AttackPower); + Base::ClearChangesMask(AttackPowerModPos); + Base::ClearChangesMask(AttackPowerModNeg); + Base::ClearChangesMask(AttackPowerMultiplier); + Base::ClearChangesMask(AttackPowerModSupport); + Base::ClearChangesMask(RangedAttackPower); + Base::ClearChangesMask(RangedAttackPowerModPos); + Base::ClearChangesMask(RangedAttackPowerModNeg); + Base::ClearChangesMask(RangedAttackPowerMultiplier); + Base::ClearChangesMask(RangedAttackPowerModSupport); + Base::ClearChangesMask(MainHandWeaponAttackPower); + Base::ClearChangesMask(OffHandWeaponAttackPower); + Base::ClearChangesMask(RangedWeaponAttackPower); + Base::ClearChangesMask(SetAttackSpeedAura); + Base::ClearChangesMask(Lifesteal); + Base::ClearChangesMask(MinRangedDamage); + Base::ClearChangesMask(MaxRangedDamage); + Base::ClearChangesMask(ManaCostMultiplier); + Base::ClearChangesMask(MaxHealthModifier); + Base::ClearChangesMask(HoverHeight); + Base::ClearChangesMask(MinItemLevelCutoff); + Base::ClearChangesMask(MinItemLevel); + Base::ClearChangesMask(MaxItemLevel); + Base::ClearChangesMask(AzeriteItemLevel); + Base::ClearChangesMask(WildBattlePetLevel); + Base::ClearChangesMask(BattlePetCompanionExperience); + Base::ClearChangesMask(BattlePetCompanionNameTimestamp); + Base::ClearChangesMask(InteractSpellID); + Base::ClearChangesMask(ScaleDuration); + Base::ClearChangesMask(LooksLikeMountID); + Base::ClearChangesMask(LooksLikeCreatureID); + Base::ClearChangesMask(LookAtControllerID); + Base::ClearChangesMask(PerksVendorItemID); + Base::ClearChangesMask(TaxiNodesID); + Base::ClearChangesMask(GuildGUID); + Base::ClearChangesMask(FlightCapabilityID); + Base::ClearChangesMask(GlideEventSpeedDivisor); + Base::ClearChangesMask(DriveCapabilityID); + Base::ClearChangesMask(MaxHealthModifierFlatNeg); + Base::ClearChangesMask(MaxHealthModifierFlatPos); + Base::ClearChangesMask(SilencedSchoolMask); + Base::ClearChangesMask(CurrentAreaID); + Base::ClearChangesMask(NameplateDistanceMod); + Base::ClearChangesMask(AutoAttackRangeMod); + Base::ClearChangesMask(NameplateAttachToGUID); + Base::ClearChangesMask(AssistActionData); + Base::ClearChangesMask(Power); + Base::ClearChangesMask(MaxPower); + Base::ClearChangesMask(PowerRegenFlatModifier); + Base::ClearChangesMask(PowerRegenInterruptedFlatModifier); + Base::ClearChangesMask(VirtualItems); + Base::ClearChangesMask(AttackRoundBaseTime); + Base::ClearChangesMask(Stats); + Base::ClearChangesMask(StatPosBuff); + Base::ClearChangesMask(StatNegBuff); + Base::ClearChangesMask(StatSupportBuff); + Base::ClearChangesMask(Resistances); + Base::ClearChangesMask(BonusResistanceMods); + Base::ClearChangesMask(ManaCostModifier); + _changesMask.ResetAll(); + } + + void ChrCustomizationChoice::WriteCreate(ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << uint32(ChrCustomizationOptionID); + data << uint32(ChrCustomizationChoiceID); + } + + void ChrCustomizationChoice::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << uint32(ChrCustomizationOptionID); + data << uint32(ChrCustomizationChoiceID); + } + + bool ChrCustomizationChoice::operator==(ChrCustomizationChoice const& right) const + { + return ChrCustomizationOptionID == right.ChrCustomizationOptionID + && ChrCustomizationChoiceID == right.ChrCustomizationChoiceID; + } + + void QuestLog::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(QuestID); + data << uint16(StateFlags); + for (uint32 i = 0; i < 24; ++i) + { + data << int16(ObjectiveProgress[i]); + } + data << int64(EndTime); + data << uint32(ObjectiveFlags); + data << uint32(EnabledObjectivesMask); + } + + void QuestLog::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlocksMask(0), 1); + if (changesMask.GetBlock(0)) + data.WriteBits(changesMask.GetBlock(0), 32); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(QuestID); + } + if (changesMask[2]) + { + data << uint16(StateFlags); + } + if (changesMask[3]) + { + data << int64(EndTime); + } + if (changesMask[4]) + { + data << uint32(ObjectiveFlags); + } + if (changesMask[5]) + { + data << uint32(EnabledObjectivesMask); + } + } + if (changesMask[6]) + { + for (uint32 i = 0; i < 24; ++i) + { + if (changesMask[7 + i]) + { + data << int16(ObjectiveProgress[i]); + } + } + } + } + + void QuestLog::ClearChangesMask() + { + Base::ClearChangesMask(QuestID); + Base::ClearChangesMask(StateFlags); + Base::ClearChangesMask(EndTime); + Base::ClearChangesMask(ObjectiveFlags); + Base::ClearChangesMask(EnabledObjectivesMask); + Base::ClearChangesMask(ObjectiveProgress); + _changesMask.ResetAll(); + } + + void ArenaCooldown::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellID); + data << int32(Charges); + data << uint32(Flags); + data << uint32(StartTime); + data << uint32(EndTime); + data << uint32(NextChargeTime); + data << uint8(MaxCharges); + } + + void ArenaCooldown::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 8); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(SpellID); + } + if (changesMask[2]) + { + data << int32(Charges); + } + if (changesMask[3]) + { + data << uint32(Flags); + } + if (changesMask[4]) + { + data << uint32(StartTime); + } + if (changesMask[5]) + { + data << uint32(EndTime); + } + if (changesMask[6]) + { + data << uint32(NextChargeTime); + } + if (changesMask[7]) + { + data << uint8(MaxCharges); + } + } + } + + void ArenaCooldown::ClearChangesMask() + { + Base::ClearChangesMask(SpellID); + Base::ClearChangesMask(Charges); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(StartTime); + Base::ClearChangesMask(EndTime); + Base::ClearChangesMask(NextChargeTime); + Base::ClearChangesMask(MaxCharges); + _changesMask.ResetAll(); + } + + void ZonePlayerForcedReaction::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(FactionID); + data << int32(Reaction); + } + + void ZonePlayerForcedReaction::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(FactionID); + } + if (changesMask[2]) + { + data << int32(Reaction); + } + } + } + + void ZonePlayerForcedReaction::ClearChangesMask() + { + Base::ClearChangesMask(FactionID); + Base::ClearChangesMask(Reaction); + _changesMask.ResetAll(); + } + + void PetCreatureName::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(CreatureID); + data.WriteBits(Name->size(), 8); + data << WorldPackets::SizedString::Data(*Name); + data.FlushBits(); + } + + void PetCreatureName::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(CreatureID); + } + if (changesMask[2]) + { + data.WriteBits(Name->size(), 8); + data << WorldPackets::SizedString::Data(*Name); + } + } + data.FlushBits(); + } + + void PetCreatureName::ClearChangesMask() + { + Base::ClearChangesMask(CreatureID); + Base::ClearChangesMask(Name); + _changesMask.ResetAll(); + } + + void CTROptions::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(ConditionalFlags.size()); + data << uint8(FactionGroup); + data << uint32(ChromieTimeExpansionMask); + for (uint32 i = 0; i < ConditionalFlags.size(); ++i) + { + data << uint32(ConditionalFlags[i]); + } + } + + void CTROptions::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(ConditionalFlags.size()); + data.FlushBits(); + data << uint8(FactionGroup); + data << uint32(ChromieTimeExpansionMask); + for (uint32 i = 0; i < ConditionalFlags.size(); ++i) + { + data << uint32(ConditionalFlags[i]); + } + } + + bool CTROptions::operator==(CTROptions const& right) const + { + return ConditionalFlags == right.ConditionalFlags + && FactionGroup == right.FactionGroup + && ChromieTimeExpansionMask == right.ChromieTimeExpansionMask; + } + + void LeaverInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << BnetAccountGUID; + data << float(LeaveScore); + data << uint32(SeasonID); + data << uint32(TotalLeaves); + data << uint32(TotalSuccesses); + data << int32(ConsecutiveSuccesses); + data << int64(LastPenaltyTime); + data << int64(LeaverExpirationTime); + data << int32(Flags); + data.WriteBit(IsLeaver); + data.FlushBits(); + } + + void LeaverInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data.FlushBits(); + data << BnetAccountGUID; + data << float(LeaveScore); + data << uint32(SeasonID); + data << uint32(TotalLeaves); + data << uint32(TotalSuccesses); + data << int32(ConsecutiveSuccesses); + data << int64(LastPenaltyTime); + data << int64(LeaverExpirationTime); + data << int32(Flags); + data.WriteBit(IsLeaver); + data.FlushBits(); + } + + bool LeaverInfo::operator==(LeaverInfo const& right) const + { + return IsLeaver == right.IsLeaver + && BnetAccountGUID == right.BnetAccountGUID + && LeaveScore == right.LeaveScore + && SeasonID == right.SeasonID + && TotalLeaves == right.TotalLeaves + && TotalSuccesses == right.TotalSuccesses + && ConsecutiveSuccesses == right.ConsecutiveSuccesses + && LastPenaltyTime == right.LastPenaltyTime + && LeaverExpirationTime == right.LeaverExpirationTime + && Flags == right.Flags; + } + + void DeclinedNames::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + for (uint32 i = 0; i < 5; ++i) + { + data.WriteBits(Name[i].size(), 10); + } + for (uint32 i = 0; i < 5; ++i) + { + data << WorldPackets::SizedString::Data(Name[i]); + } + data.FlushBits(); + } + + void DeclinedNames::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlocksMask(0), 1); + if (changesMask.GetBlock(0)) + data.WriteBits(changesMask.GetBlock(0), 32); + + if (changesMask[0]) + { + for (uint32 i = 0; i < 5; ++i) + { + if (changesMask[1 + i]) + { + data.WriteBits(Name[i].size(), 10); + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + for (uint32 i = 0; i < 5; ++i) + { + if (changesMask[1 + i]) + { + data << WorldPackets::SizedString::Data(Name[i]); + } + } + } + data.FlushBits(); + } + + void DeclinedNames::ClearChangesMask() + { + Base::ClearChangesMask(Name); + _changesMask.ResetAll(); + } + + void CustomTabardInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(EmblemStyle); + data << int32(EmblemColor); + data << int32(BorderStyle); + data << int32(BorderColor); + data << int32(BackgroundColor); + } + + void CustomTabardInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 6); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(EmblemStyle); + } + if (changesMask[2]) + { + data << int32(EmblemColor); + } + if (changesMask[3]) + { + data << int32(BorderStyle); + } + if (changesMask[4]) + { + data << int32(BorderColor); + } + if (changesMask[5]) + { + data << int32(BackgroundColor); + } + } + } + + void CustomTabardInfo::ClearChangesMask() + { + Base::ClearChangesMask(EmblemStyle); + Base::ClearChangesMask(EmblemColor); + Base::ClearChangesMask(BorderStyle); + Base::ClearChangesMask(BorderColor); + Base::ClearChangesMask(BackgroundColor); + _changesMask.ResetAll(); + } + + void NPCAsPlayerInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << int32(CharacterLoadoutID); + data << int32(CreatureID); + data << LocWorldSpace; + data << float(FacingWorldSpace); + data << TransportGUID; + } + + void NPCAsPlayerInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << int32(CharacterLoadoutID); + data << int32(CreatureID); + data << LocWorldSpace; + data << float(FacingWorldSpace); + data << TransportGUID; + } + + bool NPCAsPlayerInfo::operator==(NPCAsPlayerInfo const& right) const + { + return Field_0 == right.Field_0 + && CharacterLoadoutID == right.CharacterLoadoutID + && CreatureID == right.CreatureID + && LocWorldSpace == right.LocWorldSpace + && FacingWorldSpace == right.FacingWorldSpace + && TransportGUID == right.TransportGUID; + } + + void PlayerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << *DuelArbiter; + data << *WowAccount; + data << *BnetAccount; + data << uint64(GuildClubMemberID); + data << *LootTargetGUID; + data << uint32(PlayerFlags); + data << uint32(PlayerFlagsEx); + data << uint32(GuildRankID); + data << uint32(GuildDeleteDate); + data << int32(GuildLevel); + data << uint32(Customizations.size()); + data << uint32(RandomCustomizations.size()); + for (uint32 i = 0; i < 2; ++i) + { + data << uint8(PartyType[i]); + } + data << uint8(NativeSex); + data << uint8(Inebriation); + data << uint8(PvpTitle); + data << uint8(ArenaFaction); + data << uint32(DuelTeam); + data << int32(GuildTimeStamp); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) + { + for (uint32 i = 0; i < 175; ++i) + { + QuestLog[i].WriteCreate(data, receiver, owner); + } + data << uint32(QuestSessionQuestLog.size()); + } + data << int32(PlayerTitle); + data << int32(FakeInebriation); + data << uint32(VirtualPlayerRealm); + data << uint32(CurrentSpecID); + data << int32(CurrentCombatTraitConfigSubTreeID); + data << int32(TaxiMountAnimKitID); + for (uint32 i = 0; i < 6; ++i) + { + data << float(AvgItemLevel[i]); + } + data << uint8(CurrentBattlePetBreedQuality); + data << int32(HonorLevel); + data << int64(LogoutTime); + data << uint32(ArenaCooldowns.size()); + for (uint32 i = 0; i < 32; ++i) + { + ForcedReactions[i].WriteCreate(data, receiver, owner); + } + data << int32(OfferedAdvJournalQuestID); + data << int32(OfferedScriptQuestID); + data << int32(CurrentBattlePetSpeciesID); + data << uint32(PetNames.size()); + CtrOptions->WriteCreate(data, receiver, owner); + data << int32(CovenantID); + data << int32(SoulbindID); + data << *SpectateTarget; + data << int32(WorldLootObjectInventorySwapSlot); + data << uint32(VisualItemReplacements.size()); + for (uint32 i = 0; i < 19; ++i) + { + data << uint32(PlunderstormItemDisplayID[i]); + } + PersonalTabard->WriteCreate(data, receiver, owner); + NpcAsPlayerInfo->WriteCreate(data, receiver, owner); + for (uint32 i = 0; i < Customizations.size(); ++i) + { + Customizations[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < RandomCustomizations.size(); ++i) + { + RandomCustomizations[i].WriteCreate(data, receiver, owner); + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) + { + for (uint32 i = 0; i < QuestSessionQuestLog.size(); ++i) + { + QuestSessionQuestLog[i].WriteCreate(data, receiver, owner); + } + } + for (uint32 i = 0; i < ArenaCooldowns.size(); ++i) + { + ArenaCooldowns[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < VisualItemReplacements.size(); ++i) + { + data << int32(VisualItemReplacements[i]); + } + for (uint32 i = 0; i < 19; ++i) + { + VisibleItems[i].WriteCreate(data, receiver, owner); + } + data.FlushBits(); + data.WriteBits(Name->size(), 6); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) + { + data.WriteBit(HasQuestSession); + } + data.WriteBit(HasLevelLink); + data.WriteBits(DeclinedNames.has_value(), 1); + data << *DungeonScore; + data << WorldPackets::SizedString::Data(*Name); + LeaverInfo->WriteCreate(data, receiver, owner); + for (uint32 i = 0; i < 16; ++i) + { + data << VisibleEquipableSpells[i]; + } + for (uint32 i = 0; i < PetNames.size(); ++i) + { + PetNames[i].WriteCreate(data, receiver, owner); + } + if (DeclinedNames.has_value()) + { + DeclinedNames->WriteCreate(data, receiver, owner); + } + data.FlushBits(); + } + + static constexpr void PlayerDataAppendAllowedFieldsMaskForFlag(PlayerData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) + allowedMaskForTarget |= std::array{ 0x00000022u, 0xFFF00000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000000Fu, 0x00000000u, 0x00000000u, 0x00000000u }; + } + + void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + } + + void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) + { + Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x000FFFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFF0u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000001Fu }); + PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; + } + + void PlayerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x000FFFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFF0u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000001Fu }); + PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); + } + + void PlayerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 11); + for (uint32 i = 0; i < 11; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + bool noQuestLogChangesMask = data.WriteBit(IsQuestLogChangesMaskSkipped()); + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(HasQuestSession); + } + if (changesMask[2]) + { + data.WriteBit(HasLevelLink); + } + if (changesMask[3]) + { + if (!ignoreNestedChangesMask) + Customizations.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Customizations.size(), data); + } + if (changesMask[4]) + { + if (!ignoreNestedChangesMask) + RandomCustomizations.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(RandomCustomizations.size(), data); + } + if (changesMask[5]) + { + if (!ignoreNestedChangesMask) + QuestSessionQuestLog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(QuestSessionQuestLog.size(), data); + } + if (changesMask[6]) + { + if (!ignoreNestedChangesMask) + ArenaCooldowns.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ArenaCooldowns.size(), data); + } + if (changesMask[7]) + { + if (!ignoreNestedChangesMask) + PetNames.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(PetNames.size(), data); + } + if (changesMask[8]) + { + if (!ignoreNestedChangesMask) + VisualItemReplacements.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(VisualItemReplacements.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + for (uint32 i = 0; i < Customizations.size(); ++i) + { + if (Customizations.HasChanged(i) || ignoreNestedChangesMask) + { + Customizations[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[4]) + { + for (uint32 i = 0; i < RandomCustomizations.size(); ++i) + { + if (RandomCustomizations.HasChanged(i) || ignoreNestedChangesMask) + { + RandomCustomizations[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[5]) + { + for (uint32 i = 0; i < QuestSessionQuestLog.size(); ++i) + { + if (QuestSessionQuestLog.HasChanged(i) || ignoreNestedChangesMask) + { + if (noQuestLogChangesMask) + QuestSessionQuestLog[i].WriteCreate(data, receiver, owner); + else + QuestSessionQuestLog[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[6]) + { + for (uint32 i = 0; i < ArenaCooldowns.size(); ++i) + { + if (ArenaCooldowns.HasChanged(i) || ignoreNestedChangesMask) + { + ArenaCooldowns[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[8]) + { + for (uint32 i = 0; i < VisualItemReplacements.size(); ++i) + { + if (VisualItemReplacements.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(VisualItemReplacements[i]); + } + } + } + if (changesMask[7]) + { + for (uint32 i = 0; i < PetNames.size(); ++i) + { + if (PetNames.HasChanged(i) || ignoreNestedChangesMask) + { + PetNames[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[9]) + { + data << *DuelArbiter; + } + if (changesMask[10]) + { + data << *WowAccount; + } + if (changesMask[11]) + { + data << *BnetAccount; + } + if (changesMask[12]) + { + data << uint64(GuildClubMemberID); + } + if (changesMask[13]) + { + data << *LootTargetGUID; + } + if (changesMask[14]) + { + data << uint32(PlayerFlags); + } + if (changesMask[15]) + { + data << uint32(PlayerFlagsEx); + } + if (changesMask[16]) + { + data << uint32(GuildRankID); + } + if (changesMask[17]) + { + data << uint32(GuildDeleteDate); + } + if (changesMask[18]) + { + data << int32(GuildLevel); + } + if (changesMask[19]) + { + data << uint8(NativeSex); + } + if (changesMask[20]) + { + data << uint8(Inebriation); + } + if (changesMask[21]) + { + data << uint8(PvpTitle); + } + if (changesMask[22]) + { + data << uint8(ArenaFaction); + } + if (changesMask[23]) + { + data << uint32(DuelTeam); + } + if (changesMask[24]) + { + data << int32(GuildTimeStamp); + } + if (changesMask[25]) + { + data << int32(PlayerTitle); + } + if (changesMask[26]) + { + data << int32(FakeInebriation); + } + if (changesMask[27]) + { + data << uint32(VirtualPlayerRealm); + } + if (changesMask[28]) + { + data << uint32(CurrentSpecID); + } + if (changesMask[29]) + { + data << int32(CurrentCombatTraitConfigSubTreeID); + } + if (changesMask[30]) + { + data << int32(TaxiMountAnimKitID); + } + if (changesMask[31]) + { + data << uint8(CurrentBattlePetBreedQuality); + } + } + if (changesMask[32]) + { + if (changesMask[33]) + { + data << int32(HonorLevel); + } + if (changesMask[34]) + { + data << int64(LogoutTime); + } + if (changesMask[36]) + { + data << int32(OfferedAdvJournalQuestID); + } + if (changesMask[37]) + { + data << int32(OfferedScriptQuestID); + } + if (changesMask[38]) + { + data << int32(CurrentBattlePetSpeciesID); + } + if (changesMask[39]) + { + CtrOptions->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[40]) + { + data << int32(CovenantID); + } + if (changesMask[41]) + { + data << int32(SoulbindID); + } + if (changesMask[44]) + { + data << *SpectateTarget; + } + if (changesMask[45]) + { + data << int32(WorldLootObjectInventorySwapSlot); + } + if (changesMask[47]) + { + PersonalTabard->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[48]) + { + NpcAsPlayerInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[35]) + { + data.WriteBits(Name->size(), 6); + } + data.WriteBits(DeclinedNames.has_value(), 1); + data.FlushBits(); + if (changesMask[42]) + { + data << *DungeonScore; + } + if (changesMask[35]) + { + data << WorldPackets::SizedString::Data(*Name); + } + if (changesMask[43]) + { + LeaverInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[46]) + { + if (DeclinedNames.has_value()) + { + DeclinedNames->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[49]) + { + for (uint32 i = 0; i < 2; ++i) + { + if (changesMask[50 + i]) + { + data << uint8(PartyType[i]); + } + } + } + if (changesMask[52]) + { + for (uint32 i = 0; i < 175; ++i) + { + if (changesMask[53 + i]) + { + if (noQuestLogChangesMask) + QuestLog[i].WriteCreate(data, receiver, owner); + else + QuestLog[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[248]) + { + for (uint32 i = 0; i < 6; ++i) + { + if (changesMask[249 + i]) + { + data << float(AvgItemLevel[i]); + } + } + } + if (changesMask[255]) + { + for (uint32 i = 0; i < 32; ++i) + { + if (changesMask[256 + i]) + { + ForcedReactions[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[305]) + { + for (uint32 i = 0; i < 19; ++i) + { + if (changesMask[306 + i]) + { + data << uint32(PlunderstormItemDisplayID[i]); + } + } + } + if (changesMask[228]) + { + for (uint32 i = 0; i < 19; ++i) + { + if (changesMask[229 + i]) + { + VisibleItems[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[288]) + { + for (uint32 i = 0; i < 16; ++i) + { + if (changesMask[289 + i]) + { + data << VisibleEquipableSpells[i]; + } + } + } + data.FlushBits(); + } + + void PlayerData::ClearChangesMask() + { + Base::ClearChangesMask(HasQuestSession); + Base::ClearChangesMask(HasLevelLink); + Base::ClearChangesMask(Customizations); + Base::ClearChangesMask(RandomCustomizations); + Base::ClearChangesMask(QuestSessionQuestLog); + Base::ClearChangesMask(ArenaCooldowns); + Base::ClearChangesMask(VisualItemReplacements); + Base::ClearChangesMask(PetNames); + Base::ClearChangesMask(DuelArbiter); + Base::ClearChangesMask(WowAccount); + Base::ClearChangesMask(BnetAccount); + Base::ClearChangesMask(GuildClubMemberID); + Base::ClearChangesMask(LootTargetGUID); + Base::ClearChangesMask(PlayerFlags); + Base::ClearChangesMask(PlayerFlagsEx); + Base::ClearChangesMask(GuildRankID); + Base::ClearChangesMask(GuildDeleteDate); + Base::ClearChangesMask(GuildLevel); + Base::ClearChangesMask(NativeSex); + Base::ClearChangesMask(Inebriation); + Base::ClearChangesMask(PvpTitle); + Base::ClearChangesMask(ArenaFaction); + Base::ClearChangesMask(DuelTeam); + Base::ClearChangesMask(GuildTimeStamp); + Base::ClearChangesMask(PlayerTitle); + Base::ClearChangesMask(FakeInebriation); + Base::ClearChangesMask(VirtualPlayerRealm); + Base::ClearChangesMask(CurrentSpecID); + Base::ClearChangesMask(CurrentCombatTraitConfigSubTreeID); + Base::ClearChangesMask(TaxiMountAnimKitID); + Base::ClearChangesMask(CurrentBattlePetBreedQuality); + Base::ClearChangesMask(HonorLevel); + Base::ClearChangesMask(LogoutTime); + Base::ClearChangesMask(Name); + Base::ClearChangesMask(OfferedAdvJournalQuestID); + Base::ClearChangesMask(OfferedScriptQuestID); + Base::ClearChangesMask(CurrentBattlePetSpeciesID); + Base::ClearChangesMask(CtrOptions); + Base::ClearChangesMask(CovenantID); + Base::ClearChangesMask(SoulbindID); + Base::ClearChangesMask(DungeonScore); + Base::ClearChangesMask(LeaverInfo); + Base::ClearChangesMask(SpectateTarget); + Base::ClearChangesMask(WorldLootObjectInventorySwapSlot); + Base::ClearChangesMask(DeclinedNames); + Base::ClearChangesMask(PersonalTabard); + Base::ClearChangesMask(NpcAsPlayerInfo); + Base::ClearChangesMask(PartyType); + Base::ClearChangesMask(QuestLog); + Base::ClearChangesMask(VisibleItems); + Base::ClearChangesMask(AvgItemLevel); + Base::ClearChangesMask(ForcedReactions); + Base::ClearChangesMask(VisibleEquipableSpells); + Base::ClearChangesMask(PlunderstormItemDisplayID); + _changesMask.ResetAll(); + } + + void SkillInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + for (uint32 i = 0; i < 300; ++i) + { + data << uint16(SkillLineID[i]); + data << uint16(SkillStep[i]); + data << uint16(SkillRank[i]); + data << uint16(SkillStartingRank[i]); + data << uint16(SkillMaxRank[i]); + data << int16(SkillTempBonus[i]); + data << uint16(SkillPermBonus[i]); + } + } + + void SkillInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + for (uint32 i = 0; i < 2; ++i) + data << uint32(changesMask.GetBlocksMask(i)); + data.WriteBits(changesMask.GetBlocksMask(2), 2); + for (uint32 i = 0; i < 66; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + data.FlushBits(); + if (changesMask[0]) + { + for (uint32 i = 0; i < 300; ++i) + { + if (changesMask[1 + i]) + { + data << uint16(SkillLineID[i]); + } + if (changesMask[301 + i]) + { + data << uint16(SkillStep[i]); + } + if (changesMask[601 + i]) + { + data << uint16(SkillRank[i]); + } + if (changesMask[901 + i]) + { + data << uint16(SkillStartingRank[i]); + } + if (changesMask[1201 + i]) + { + data << uint16(SkillMaxRank[i]); + } + if (changesMask[1501 + i]) + { + data << int16(SkillTempBonus[i]); + } + if (changesMask[1801 + i]) + { + data << uint16(SkillPermBonus[i]); + } + } + } + } + + void SkillInfo::ClearChangesMask() + { + Base::ClearChangesMask(SkillLineID); + Base::ClearChangesMask(SkillStep); + Base::ClearChangesMask(SkillRank); + Base::ClearChangesMask(SkillStartingRank); + Base::ClearChangesMask(SkillMaxRank); + Base::ClearChangesMask(SkillTempBonus); + Base::ClearChangesMask(SkillPermBonus); + _changesMask.ResetAll(); + } + + void BitVector::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(Values.size()); + for (uint32 i = 0; i < Values.size(); ++i) + { + data << uint64(Values[i]); + } + } + + void BitVector::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Values.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Values.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Values.size(); ++i) + { + if (Values.HasChanged(i) || ignoreChangesMask) + { + data << uint64(Values[i]); + } + } + } + } + } + + void BitVector::ClearChangesMask() + { + Base::ClearChangesMask(Values); + _changesMask.ResetAll(); + } + + void BitVectors::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const { for (uint32 i = 0; i < 14; ++i) { - if (changesMask[1 + i]) + Values[i].WriteCreate(data, receiver, owner); + } + } + + void BitVectors::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlocksMask(0), 1); + if (changesMask.GetBlock(0)) + data.WriteBits(changesMask.GetBlock(0), 32); + + data.FlushBits(); + if (changesMask[0]) + { + for (uint32 i = 0; i < 14; ++i) { - Values[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + if (changesMask[1 + i]) + { + Values[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } } } } -} -void BitVectors::ClearChangesMask() -{ - Base::ClearChangesMask(Values); - _changesMask.ResetAll(); -} - -void PlayerDataElement::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(Type); - if (Type == 1) + void BitVectors::ClearChangesMask() { - data << float(FloatValue); + Base::ClearChangesMask(Values); + _changesMask.ResetAll(); } - if (Type == 0) + + void PlayerDataElement::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const { - data << int64(Int64Value); - } -} - -void PlayerDataElement::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(Type); - if (Type == 1) - { - data << float(FloatValue); - } - if (Type == 0) - { - data << int64(Int64Value); - } -} - -bool PlayerDataElement::operator==(PlayerDataElement const& right) const -{ - return Type == right.Type - && FloatValue == right.FloatValue - && Int64Value == right.Int64Value; -} - -void RestInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(Threshold); - data << uint8(StateID); -} - -void RestInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) + data << uint32(Type); + if (Type == 1) { - data << uint32(Threshold); + data << float(FloatValue); } - if (changesMask[2]) + if (Type == 0) { - data << uint8(StateID); + data << int64(Int64Value); } } -} -void RestInfo::ClearChangesMask() -{ - Base::ClearChangesMask(Threshold); - Base::ClearChangesMask(StateID); - _changesMask.ResetAll(); -} - -void PVPInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int8(Bracket); - data << int32(PvpRatingID); - data << uint32(WeeklyPlayed); - data << uint32(WeeklyWon); - data << uint32(SeasonPlayed); - data << uint32(SeasonWon); - data << uint32(Rating); - data << uint32(WeeklyBestRating); - data << uint32(LastWeeksBestRating); - data << uint32(PvpTierID); - data << uint32(WeeklyBestWinPvpTierID); - data << uint32(SeasonBestRating); - data << uint32(SeasonBestTier); - data << uint32(WeeklyRoundsPlayed); - data << uint32(WeeklyRoundsWon); - data << uint32(SeasonRoundsPlayed); - data << uint32(SeasonRoundsWon); - data.WriteBit(Disqualified); - data.FlushBits(); -} - -void PVPInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 19); - - if (changesMask[0]) + void PlayerDataElement::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const { - if (changesMask[1]) + data << uint32(Type); + if (Type == 1) { - data.WriteBit(Disqualified); + data << float(FloatValue); + } + if (Type == 0) + { + data << int64(Int64Value); } } - data.FlushBits(); - if (changesMask[0]) + + bool PlayerDataElement::operator==(PlayerDataElement const& right) const { - if (changesMask[2]) + return Type == right.Type + && FloatValue == right.FloatValue + && Int64Value == right.Int64Value; + } + + void RestInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(Threshold); + data << uint8(StateID); + } + + void RestInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) { - data << int8(Bracket); + if (changesMask[1]) + { + data << uint32(Threshold); + } + if (changesMask[2]) + { + data << uint8(StateID); + } } - if (changesMask[3]) + } + + void RestInfo::ClearChangesMask() + { + Base::ClearChangesMask(Threshold); + Base::ClearChangesMask(StateID); + _changesMask.ResetAll(); + } + + void PVPInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int8(Bracket); + data << int32(PvpRatingID); + data << uint32(WeeklyPlayed); + data << uint32(WeeklyWon); + data << uint32(SeasonPlayed); + data << uint32(SeasonWon); + data << uint32(Rating); + data << uint32(WeeklyBestRating); + data << uint32(LastWeeksBestRating); + data << uint32(PvpTierID); + data << uint32(WeeklyBestWinPvpTierID); + data << uint32(SeasonBestRating); + data << uint32(SeasonBestTier); + data << uint32(WeeklyRoundsPlayed); + data << uint32(WeeklyRoundsWon); + data << uint32(SeasonRoundsPlayed); + data << uint32(SeasonRoundsWon); + data.WriteBit(Disqualified); + data.FlushBits(); + } + + void PVPInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 19); + + if (changesMask[0]) { - data << int32(PvpRatingID); + if (changesMask[1]) + { + data.WriteBit(Disqualified); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + data << int8(Bracket); + } + if (changesMask[3]) + { + data << int32(PvpRatingID); + } + if (changesMask[4]) + { + data << uint32(WeeklyPlayed); + } + if (changesMask[5]) + { + data << uint32(WeeklyWon); + } + if (changesMask[6]) + { + data << uint32(SeasonPlayed); + } + if (changesMask[7]) + { + data << uint32(SeasonWon); + } + if (changesMask[8]) + { + data << uint32(Rating); + } + if (changesMask[9]) + { + data << uint32(WeeklyBestRating); + } + if (changesMask[10]) + { + data << uint32(LastWeeksBestRating); + } + if (changesMask[11]) + { + data << uint32(PvpTierID); + } + if (changesMask[12]) + { + data << uint32(WeeklyBestWinPvpTierID); + } + if (changesMask[13]) + { + data << uint32(SeasonBestRating); + } + if (changesMask[14]) + { + data << uint32(SeasonBestTier); + } + if (changesMask[15]) + { + data << uint32(WeeklyRoundsPlayed); + } + if (changesMask[16]) + { + data << uint32(WeeklyRoundsWon); + } + if (changesMask[17]) + { + data << uint32(SeasonRoundsPlayed); + } + if (changesMask[18]) + { + data << uint32(SeasonRoundsWon); + } + } + data.FlushBits(); + } + + void PVPInfo::ClearChangesMask() + { + Base::ClearChangesMask(Disqualified); + Base::ClearChangesMask(Bracket); + Base::ClearChangesMask(PvpRatingID); + Base::ClearChangesMask(WeeklyPlayed); + Base::ClearChangesMask(WeeklyWon); + Base::ClearChangesMask(SeasonPlayed); + Base::ClearChangesMask(SeasonWon); + Base::ClearChangesMask(Rating); + Base::ClearChangesMask(WeeklyBestRating); + Base::ClearChangesMask(LastWeeksBestRating); + Base::ClearChangesMask(PvpTierID); + Base::ClearChangesMask(WeeklyBestWinPvpTierID); + Base::ClearChangesMask(SeasonBestRating); + Base::ClearChangesMask(SeasonBestTier); + Base::ClearChangesMask(WeeklyRoundsPlayed); + Base::ClearChangesMask(WeeklyRoundsWon); + Base::ClearChangesMask(SeasonRoundsPlayed); + Base::ClearChangesMask(SeasonRoundsWon); + _changesMask.ResetAll(); + } + + void CharacterRestriction::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << int32(Field_4); + data << int32(Field_8); + data.WriteBits(Type, 5); + data.FlushBits(); + } + + void CharacterRestriction::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << int32(Field_4); + data << int32(Field_8); + data.WriteBits(Type, 5); + data.FlushBits(); + } + + bool CharacterRestriction::operator==(CharacterRestriction const& right) const + { + return Field_0 == right.Field_0 + && Field_4 == right.Field_4 + && Field_8 == right.Field_8 + && Type == right.Type; + } + + void SpellPctModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(ModIndex); + data << float(ModifierValue); + data << int32(LabelID); + } + + void SpellPctModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(ModIndex); + data << float(ModifierValue); + data << int32(LabelID); + } + + bool SpellPctModByLabel::operator==(SpellPctModByLabel const& right) const + { + return ModIndex == right.ModIndex + && ModifierValue == right.ModifierValue + && LabelID == right.LabelID; + } + + void SpellFlatModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(ModIndex); + data << int32(ModifierValue); + data << int32(LabelID); + } + + void SpellFlatModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(ModIndex); + data << int32(ModifierValue); + data << int32(LabelID); + } + + bool SpellFlatModByLabel::operator==(SpellFlatModByLabel const& right) const + { + return ModIndex == right.ModIndex + && ModifierValue == right.ModifierValue + && LabelID == right.LabelID; + } + + void SpellPctPVPModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(PvpModIndex); + data << float(ModifierValue); + data << int32(LabelID); + } + + void SpellPctPVPModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(PvpModIndex); + data << float(ModifierValue); + data << int32(LabelID); + } + + bool SpellPctPVPModByLabel::operator==(SpellPctPVPModByLabel const& right) const + { + return PvpModIndex == right.PvpModIndex + && ModifierValue == right.ModifierValue + && LabelID == right.LabelID; + } + + void SpellFlatPVPModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(PvpModIndex); + data << int32(ModifierValue); + data << int32(LabelID); + } + + void SpellFlatPVPModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(PvpModIndex); + data << int32(ModifierValue); + data << int32(LabelID); + } + + bool SpellFlatPVPModByLabel::operator==(SpellFlatPVPModByLabel const& right) const + { + return PvpModIndex == right.PvpModIndex + && ModifierValue == right.ModifierValue + && LabelID == right.LabelID; + } + + void CompletedProject::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int64(FirstCompleted); + data << uint32(ProjectID); + data << uint32(CompletionCount); + } + + void CompletedProject::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int64(FirstCompleted); + } + if (changesMask[2]) + { + data << uint32(ProjectID); + } + if (changesMask[3]) + { + data << uint32(CompletionCount); + } + } + } + + void CompletedProject::ClearChangesMask() + { + Base::ClearChangesMask(FirstCompleted); + Base::ClearChangesMask(ProjectID); + Base::ClearChangesMask(CompletionCount); + _changesMask.ResetAll(); + } + + void ResearchHistory::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(CompletedProjects.size()); + for (uint32 i = 0; i < CompletedProjects.size(); ++i) + { + CompletedProjects[i].WriteCreate(data, receiver, owner); + } + } + + void ResearchHistory::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + CompletedProjects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CompletedProjects.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < CompletedProjects.size(); ++i) + { + if (CompletedProjects.HasChanged(i) || ignoreChangesMask) + { + CompletedProjects[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + } + } + + void ResearchHistory::ClearChangesMask() + { + Base::ClearChangesMask(CompletedProjects); + _changesMask.ResetAll(); + } + + void MawPower::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellID); + data << int32(MawPowerID); + data << int32(Stacks); + } + + void MawPower::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellID); + data << int32(MawPowerID); + data << int32(Stacks); + } + + bool MawPower::operator==(MawPower const& right) const + { + return SpellID == right.SpellID + && MawPowerID == right.MawPowerID + && Stacks == right.Stacks; + } + + void MultiFloorExplore::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(WorldMapOverlayIDs.size()); + for (uint32 i = 0; i < WorldMapOverlayIDs.size(); ++i) + { + data << int32(WorldMapOverlayIDs[i]); + } + } + + void MultiFloorExplore::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(WorldMapOverlayIDs.size()); + for (uint32 i = 0; i < WorldMapOverlayIDs.size(); ++i) + { + data << int32(WorldMapOverlayIDs[i]); + } + data.FlushBits(); + } + + bool MultiFloorExplore::operator==(MultiFloorExplore const& right) const + { + return WorldMapOverlayIDs == right.WorldMapOverlayIDs; + } + + void RecipeProgressionInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint16(RecipeProgressionGroupID); + data << uint16(Experience); + } + + void RecipeProgressionInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint16(RecipeProgressionGroupID); + data << uint16(Experience); + } + + bool RecipeProgressionInfo::operator==(RecipeProgressionInfo const& right) const + { + return RecipeProgressionGroupID == right.RecipeProgressionGroupID + && Experience == right.Experience; + } + + void LevelLinkInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << *TargetGUID; + data << int32(Level); + } + + void LevelLinkInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *TargetGUID; + } + if (changesMask[2]) + { + data << int32(Level); + } + } + } + + void LevelLinkInfo::ClearChangesMask() + { + Base::ClearChangesMask(TargetGUID); + Base::ClearChangesMask(Level); + _changesMask.ResetAll(); + } + + void QuestSession::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << *Owner; + QuestCompleted->WriteCreate(data, receiver, owner); + } + + void QuestSession::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *Owner; + } + if (changesMask[2]) + { + QuestCompleted->WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + + void QuestSession::ClearChangesMask() + { + Base::ClearChangesMask(Owner); + Base::ClearChangesMask(QuestCompleted); + _changesMask.ResetAll(); + } + + void ReplayedQuest::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(QuestID); + data << uint32(ReplayTime); + } + + void ReplayedQuest::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(QuestID); + } + if (changesMask[2]) + { + data << uint32(ReplayTime); + } + } + } + + void ReplayedQuest::ClearChangesMask() + { + Base::ClearChangesMask(QuestID); + Base::ClearChangesMask(ReplayTime); + _changesMask.ResetAll(); + } + + void TraitEntry::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(TraitNodeID); + data << int32(TraitNodeEntryID); + data << int32(Rank); + data << int32(GrantedRanks); + data << int32(BonusRanks); + } + + void TraitEntry::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(TraitNodeID); + data << int32(TraitNodeEntryID); + data << int32(Rank); + data << int32(GrantedRanks); + data << int32(BonusRanks); + } + + bool TraitEntry::operator==(TraitEntry const& right) const + { + return TraitNodeID == right.TraitNodeID + && TraitNodeEntryID == right.TraitNodeEntryID + && Rank == right.Rank + && GrantedRanks == right.GrantedRanks + && BonusRanks == right.BonusRanks; + } + + void TraitSubTreeCache::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(TraitSubTreeID); + data << uint32(Entries.size()); + for (uint32 i = 0; i < Entries.size(); ++i) + { + Entries[i].WriteCreate(data, receiver, owner); + } + data.WriteBits(Active, 1); + data.FlushBits(); + } + + void TraitSubTreeCache::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(TraitSubTreeID); + data << uint32(Entries.size()); + for (uint32 i = 0; i < Entries.size(); ++i) + { + Entries[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + data.FlushBits(); + data.WriteBits(Active, 1); + data.FlushBits(); + } + + bool TraitSubTreeCache::operator==(TraitSubTreeCache const& right) const + { + return Entries == right.Entries + && TraitSubTreeID == right.TraitSubTreeID + && Active == right.Active; + } + + void TraitConfig::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(ID); + data << int32(Type); + data << uint32(Entries.size()); + data << uint32(SubTrees.size()); + if (Type == 2) + { + data << int32(SkillLineID); + } + if (Type == 1) + { + data << int32(ChrSpecializationID); + data << int32(CombatConfigFlags); + data << int32(LocalIdentifier); + } + if (Type == 3) + { + data << int32(TraitSystemID); + data << int32(VariationID); + } + for (uint32 i = 0; i < Entries.size(); ++i) + { + Entries[i].WriteCreate(data, receiver, owner); + } + data.WriteBits(Name->size(), 9); + for (uint32 i = 0; i < SubTrees.size(); ++i) + { + SubTrees[i].WriteCreate(data, receiver, owner); + } + data << WorldPackets::SizedString::Data(*Name); + data.FlushBits(); + } + + void TraitConfig::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 15); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Entries.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Entries.size(), data); + } + if (changesMask[2]) + { + if (!ignoreChangesMask) + SubTrees.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SubTrees.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Entries.size(); ++i) + { + if (Entries.HasChanged(i) || ignoreChangesMask) + { + Entries[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < SubTrees.size(); ++i) + { + if (SubTrees.HasChanged(i) || ignoreChangesMask) + { + SubTrees[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + if (changesMask[3]) + { + data << int32(ID); + } } if (changesMask[4]) { - data << uint32(WeeklyPlayed); - } - if (changesMask[5]) - { - data << uint32(WeeklyWon); - } - if (changesMask[6]) - { - data << uint32(SeasonPlayed); - } - if (changesMask[7]) - { - data << uint32(SeasonWon); + if (changesMask[6]) + { + data << int32(Type); + } + if (changesMask[7]) + { + if (Type == 2) + { + data << int32(SkillLineID); + } + } } if (changesMask[8]) { - data << uint32(Rating); - } - if (changesMask[9]) - { - data << uint32(WeeklyBestRating); - } - if (changesMask[10]) - { - data << uint32(LastWeeksBestRating); - } - if (changesMask[11]) - { - data << uint32(PvpTierID); + if (changesMask[9]) + { + if (Type == 1) + { + data << int32(ChrSpecializationID); + } + } + if (changesMask[10]) + { + if (Type == 1) + { + data << int32(CombatConfigFlags); + } + } + if (changesMask[11]) + { + if (Type == 1) + { + data << int32(LocalIdentifier); + } + } } if (changesMask[12]) { - data << uint32(WeeklyBestWinPvpTierID); - } - if (changesMask[13]) - { - data << uint32(SeasonBestRating); - } - if (changesMask[14]) - { - data << uint32(SeasonBestTier); - } - if (changesMask[15]) - { - data << uint32(WeeklyRoundsPlayed); - } - if (changesMask[16]) - { - data << uint32(WeeklyRoundsWon); - } - if (changesMask[17]) - { - data << uint32(SeasonRoundsPlayed); - } - if (changesMask[18]) - { - data << uint32(SeasonRoundsWon); - } - } - data.FlushBits(); -} - -void PVPInfo::ClearChangesMask() -{ - Base::ClearChangesMask(Disqualified); - Base::ClearChangesMask(Bracket); - Base::ClearChangesMask(PvpRatingID); - Base::ClearChangesMask(WeeklyPlayed); - Base::ClearChangesMask(WeeklyWon); - Base::ClearChangesMask(SeasonPlayed); - Base::ClearChangesMask(SeasonWon); - Base::ClearChangesMask(Rating); - Base::ClearChangesMask(WeeklyBestRating); - Base::ClearChangesMask(LastWeeksBestRating); - Base::ClearChangesMask(PvpTierID); - Base::ClearChangesMask(WeeklyBestWinPvpTierID); - Base::ClearChangesMask(SeasonBestRating); - Base::ClearChangesMask(SeasonBestTier); - Base::ClearChangesMask(WeeklyRoundsPlayed); - Base::ClearChangesMask(WeeklyRoundsWon); - Base::ClearChangesMask(SeasonRoundsPlayed); - Base::ClearChangesMask(SeasonRoundsWon); - _changesMask.ResetAll(); -} - -void CharacterRestriction::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << int32(Field_4); - data << int32(Field_8); - data.WriteBits(Type, 5); - data.FlushBits(); -} - -void CharacterRestriction::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << int32(Field_4); - data << int32(Field_8); - data.WriteBits(Type, 5); - data.FlushBits(); -} - -bool CharacterRestriction::operator==(CharacterRestriction const& right) const -{ - return Field_0 == right.Field_0 - && Field_4 == right.Field_4 - && Field_8 == right.Field_8 - && Type == right.Type; -} - -void SpellPctModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(ModIndex); - data << float(ModifierValue); - data << int32(LabelID); -} - -void SpellPctModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(ModIndex); - data << float(ModifierValue); - data << int32(LabelID); -} - -bool SpellPctModByLabel::operator==(SpellPctModByLabel const& right) const -{ - return ModIndex == right.ModIndex - && ModifierValue == right.ModifierValue - && LabelID == right.LabelID; -} - -void SpellFlatModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(ModIndex); - data << int32(ModifierValue); - data << int32(LabelID); -} - -void SpellFlatModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(ModIndex); - data << int32(ModifierValue); - data << int32(LabelID); -} - -bool SpellFlatModByLabel::operator==(SpellFlatModByLabel const& right) const -{ - return ModIndex == right.ModIndex - && ModifierValue == right.ModifierValue - && LabelID == right.LabelID; -} - -void SpellPctPVPModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(PvpModIndex); - data << float(ModifierValue); - data << int32(LabelID); -} - -void SpellPctPVPModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(PvpModIndex); - data << float(ModifierValue); - data << int32(LabelID); -} - -bool SpellPctPVPModByLabel::operator==(SpellPctPVPModByLabel const& right) const -{ - return PvpModIndex == right.PvpModIndex - && ModifierValue == right.ModifierValue - && LabelID == right.LabelID; -} - -void SpellFlatPVPModByLabel::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(PvpModIndex); - data << int32(ModifierValue); - data << int32(LabelID); -} - -void SpellFlatPVPModByLabel::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(PvpModIndex); - data << int32(ModifierValue); - data << int32(LabelID); -} - -bool SpellFlatPVPModByLabel::operator==(SpellFlatPVPModByLabel const& right) const -{ - return PvpModIndex == right.PvpModIndex - && ModifierValue == right.ModifierValue - && LabelID == right.LabelID; -} - -void CompletedProject::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int64(FirstCompleted); - data << uint32(ProjectID); - data << uint32(CompletionCount); -} - -void CompletedProject::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int64(FirstCompleted); - } - if (changesMask[2]) - { - data << uint32(ProjectID); - } - if (changesMask[3]) - { - data << uint32(CompletionCount); - } - } -} - -void CompletedProject::ClearChangesMask() -{ - Base::ClearChangesMask(FirstCompleted); - Base::ClearChangesMask(ProjectID); - Base::ClearChangesMask(CompletionCount); - _changesMask.ResetAll(); -} - -void ResearchHistory::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(CompletedProjects.size()); - for (uint32 i = 0; i < CompletedProjects.size(); ++i) - { - CompletedProjects[i].WriteCreate(data, receiver, owner); - } -} - -void ResearchHistory::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 2); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreChangesMask) - CompletedProjects.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CompletedProjects.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < CompletedProjects.size(); ++i) + if (changesMask[13]) { - if (CompletedProjects.HasChanged(i) || ignoreChangesMask) + if (Type == 3) { - CompletedProjects[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + data << int32(TraitSystemID); + } + } + if (changesMask[14]) + { + if (Type == 3) + { + data << int32(VariationID); } } } - } -} - -void ResearchHistory::ClearChangesMask() -{ - Base::ClearChangesMask(CompletedProjects); - _changesMask.ResetAll(); -} - -void MawPower::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellID); - data << int32(MawPowerID); - data << int32(Stacks); -} - -void MawPower::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellID); - data << int32(MawPowerID); - data << int32(Stacks); -} - -bool MawPower::operator==(MawPower const& right) const -{ - return SpellID == right.SpellID - && MawPowerID == right.MawPowerID - && Stacks == right.Stacks; -} - -void MultiFloorExplore::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(WorldMapOverlayIDs.size()); - for (uint32 i = 0; i < WorldMapOverlayIDs.size(); ++i) - { - data << int32(WorldMapOverlayIDs[i]); - } -} - -void MultiFloorExplore::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(WorldMapOverlayIDs.size()); - for (uint32 i = 0; i < WorldMapOverlayIDs.size(); ++i) - { - data << int32(WorldMapOverlayIDs[i]); - } - data.FlushBits(); -} - -bool MultiFloorExplore::operator==(MultiFloorExplore const& right) const -{ - return WorldMapOverlayIDs == right.WorldMapOverlayIDs; -} - -void RecipeProgressionInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint16(RecipeProgressionGroupID); - data << uint16(Experience); -} - -void RecipeProgressionInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint16(RecipeProgressionGroupID); - data << uint16(Experience); -} - -bool RecipeProgressionInfo::operator==(RecipeProgressionInfo const& right) const -{ - return RecipeProgressionGroupID == right.RecipeProgressionGroupID - && Experience == right.Experience; -} - -void LevelLinkInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << *TargetGUID; - data << int32(Level); -} - -void LevelLinkInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) + if (changesMask[4]) { - data << *TargetGUID; - } - if (changesMask[2]) - { - data << int32(Level); - } - } -} - -void LevelLinkInfo::ClearChangesMask() -{ - Base::ClearChangesMask(TargetGUID); - Base::ClearChangesMask(Level); - _changesMask.ResetAll(); -} - -void QuestSession::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << *Owner; - QuestCompleted->WriteCreate(data, receiver, owner); -} - -void QuestSession::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *Owner; - } - if (changesMask[2]) - { - QuestCompleted->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } -} - -void QuestSession::ClearChangesMask() -{ - Base::ClearChangesMask(Owner); - Base::ClearChangesMask(QuestCompleted); - _changesMask.ResetAll(); -} - -void ReplayedQuest::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(QuestID); - data << uint32(ReplayTime); -} - -void ReplayedQuest::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(QuestID); - } - if (changesMask[2]) - { - data << uint32(ReplayTime); - } - } -} - -void ReplayedQuest::ClearChangesMask() -{ - Base::ClearChangesMask(QuestID); - Base::ClearChangesMask(ReplayTime); - _changesMask.ResetAll(); -} - -void TraitEntry::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(TraitNodeID); - data << int32(TraitNodeEntryID); - data << int32(Rank); - data << int32(GrantedRanks); - data << int32(BonusRanks); -} - -void TraitEntry::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(TraitNodeID); - data << int32(TraitNodeEntryID); - data << int32(Rank); - data << int32(GrantedRanks); - data << int32(BonusRanks); -} - -bool TraitEntry::operator==(TraitEntry const& right) const -{ - return TraitNodeID == right.TraitNodeID - && TraitNodeEntryID == right.TraitNodeEntryID - && Rank == right.Rank - && GrantedRanks == right.GrantedRanks - && BonusRanks == right.BonusRanks; -} - -void TraitSubTreeCache::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(TraitSubTreeID); - data << uint32(Entries.size()); - for (uint32 i = 0; i < Entries.size(); ++i) - { - Entries[i].WriteCreate(data, receiver, owner); - } - data.WriteBits(Active, 1); - data.FlushBits(); -} - -void TraitSubTreeCache::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(TraitSubTreeID); - data << uint32(Entries.size()); - for (uint32 i = 0; i < Entries.size(); ++i) - { - Entries[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - data.FlushBits(); - data.WriteBits(Active, 1); - data.FlushBits(); -} - -bool TraitSubTreeCache::operator==(TraitSubTreeCache const& right) const -{ - return Entries == right.Entries - && TraitSubTreeID == right.TraitSubTreeID - && Active == right.Active; -} - -void TraitConfig::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(ID); - data << int32(Type); - data << uint32(Entries.size()); - data << uint32(SubTrees.size()); - if (Type == 2) - { - data << int32(SkillLineID); - } - if (Type == 1) - { - data << int32(ChrSpecializationID); - data << int32(CombatConfigFlags); - data << int32(LocalIdentifier); - } - if (Type == 3) - { - data << int32(TraitSystemID); - data << int32(VariationID); - } - for (uint32 i = 0; i < Entries.size(); ++i) - { - Entries[i].WriteCreate(data, receiver, owner); - } - data.WriteBits(Name->size(), 9); - for (uint32 i = 0; i < SubTrees.size(); ++i) - { - SubTrees[i].WriteCreate(data, receiver, owner); - } - data << WorldPackets::SizedString::Data(*Name); - data.FlushBits(); -} - -void TraitConfig::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 15); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreChangesMask) - Entries.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Entries.size(), data); - } - if (changesMask[2]) - { - if (!ignoreChangesMask) - SubTrees.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SubTrees.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < Entries.size(); ++i) + if (changesMask[5]) { - if (Entries.HasChanged(i) || ignoreChangesMask) - { - Entries[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } + data.WriteBits(Name->size(), 9); + data << WorldPackets::SizedString::Data(*Name); } } - if (changesMask[2]) - { - for (uint32 i = 0; i < SubTrees.size(); ++i) - { - if (SubTrees.HasChanged(i) || ignoreChangesMask) - { - SubTrees[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - } - if (changesMask[3]) - { - data << int32(ID); - } + data.FlushBits(); } - if (changesMask[4]) - { - if (changesMask[6]) - { - data << int32(Type); - } - if (changesMask[7]) - { - if (Type == 2) - { - data << int32(SkillLineID); - } - } - } - if (changesMask[8]) - { - if (changesMask[9]) - { - if (Type == 1) - { - data << int32(ChrSpecializationID); - } - } - if (changesMask[10]) - { - if (Type == 1) - { - data << int32(CombatConfigFlags); - } - } - if (changesMask[11]) - { - if (Type == 1) - { - data << int32(LocalIdentifier); - } - } - } - if (changesMask[12]) - { - if (changesMask[13]) - { - if (Type == 3) - { - data << int32(TraitSystemID); - } - } - if (changesMask[14]) - { - if (Type == 3) - { - data << int32(VariationID); - } - } - } - if (changesMask[4]) - { - if (changesMask[5]) - { - data.WriteBits(Name->size(), 9); - data << WorldPackets::SizedString::Data(*Name); - } - } - data.FlushBits(); -} -void TraitConfig::ClearChangesMask() -{ - Base::ClearChangesMask(Entries); - Base::ClearChangesMask(SubTrees); - Base::ClearChangesMask(ID); - Base::ClearChangesMask(Name); - Base::ClearChangesMask(Type); - Base::ClearChangesMask(SkillLineID); - Base::ClearChangesMask(ChrSpecializationID); - Base::ClearChangesMask(CombatConfigFlags); - Base::ClearChangesMask(LocalIdentifier); - Base::ClearChangesMask(TraitSystemID); - Base::ClearChangesMask(VariationID); - _changesMask.ResetAll(); -} - -void CraftingOrderItem::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint64(OrderItemID); - data << *ItemGUID; - data << *OwnerGUID; - data << int32(ItemID); - data << uint32(Quantity); - data << int32(ReagentQuality); - data.WriteBits(DataSlotIndex.has_value(), 1); - data.FlushBits(); - if (DataSlotIndex.has_value()) + void TraitConfig::ClearChangesMask() { - data << uint8(DataSlotIndex); + Base::ClearChangesMask(Entries); + Base::ClearChangesMask(SubTrees); + Base::ClearChangesMask(ID); + Base::ClearChangesMask(Name); + Base::ClearChangesMask(Type); + Base::ClearChangesMask(SkillLineID); + Base::ClearChangesMask(ChrSpecializationID); + Base::ClearChangesMask(CombatConfigFlags); + Base::ClearChangesMask(LocalIdentifier); + Base::ClearChangesMask(TraitSystemID); + Base::ClearChangesMask(VariationID); + _changesMask.ResetAll(); } -} -void CraftingOrderItem::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 7); - - data.FlushBits(); - if (changesMask[0]) + void CraftingOrderItem::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const { data << uint64(OrderItemID); - } - if (changesMask[1]) - { data << *ItemGUID; - } - if (changesMask[2]) - { data << *OwnerGUID; - } - if (changesMask[3]) - { data << int32(ItemID); - } - if (changesMask[4]) - { data << uint32(Quantity); - } - if (changesMask[5]) - { data << int32(ReagentQuality); - } - data.WriteBits(DataSlotIndex.has_value(), 1); - data.FlushBits(); - if (changesMask[6]) - { + data.WriteBits(DataSlotIndex.has_value(), 1); + data.FlushBits(); if (DataSlotIndex.has_value()) { data << uint8(DataSlotIndex); } } -} -void CraftingOrderItem::ClearChangesMask() -{ - Base::ClearChangesMask(OrderItemID); - Base::ClearChangesMask(ItemGUID); - Base::ClearChangesMask(OwnerGUID); - Base::ClearChangesMask(ItemID); - Base::ClearChangesMask(Quantity); - Base::ClearChangesMask(ReagentQuality); - Base::ClearChangesMask(DataSlotIndex); - _changesMask.ResetAll(); -} - -void CraftingOrderCustomer::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << *CustomerGUID; - data << *CustomerAccountGUID; -} - -void CraftingOrderCustomer::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 2); - - data.FlushBits(); - if (changesMask[0]) - { - data << *CustomerGUID; - } - if (changesMask[1]) - { - data << *CustomerAccountGUID; - } -} - -void CraftingOrderCustomer::ClearChangesMask() -{ - Base::ClearChangesMask(CustomerGUID); - Base::ClearChangesMask(CustomerAccountGUID); - _changesMask.ResetAll(); -} - -void CraftingOrderNpcCustomer::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int64(NpcCraftingOrderCustomerID); - data << int32(RealmAddress); -} - -void CraftingOrderNpcCustomer::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 2); - - data.FlushBits(); - if (changesMask[0]) - { - data << int64(NpcCraftingOrderCustomerID); - } - if (changesMask[1]) - { - data << int32(RealmAddress); - } -} - -void CraftingOrderNpcCustomer::ClearChangesMask() -{ - Base::ClearChangesMask(NpcCraftingOrderCustomerID); - Base::ClearChangesMask(RealmAddress); - _changesMask.ResetAll(); -} - -void CraftingOrderData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << uint64(OrderID); - data << int32(SkillLineAbilityID); - data << int32(OrderState); - data << uint8(OrderType); - data << uint8(MinQuality); - data << int64(ExpirationTime); - data << int64(ClaimEndTime); - data << int64(TipAmount); - data << int64(ConsortiumCut); - data << uint32(Flags); - data << *CrafterGUID; - data << *PersonalCrafterGUID; - data << int32(NpcCraftingOrderSetID); - data << int32(NpcTreasureID); - data << uint32(Reagents.size()); - data.WriteBits(CustomerNotes->size(), 10); - data.WriteBits(Customer.has_value(), 1); - data.WriteBits(NpcCustomer.has_value(), 1); - data.WriteBits(OutputItem.has_value(), 1); - data.WriteBits(OutputItemData.has_value(), 1); - data.FlushBits(); - for (uint32 i = 0; i < Reagents.size(); ++i) - { - Reagents[i].WriteCreate(data, receiver, owner); - } - data << WorldPackets::SizedString::Data(*CustomerNotes); - if (Customer.has_value()) - { - Customer->WriteCreate(data, receiver, owner); - } - if (NpcCustomer.has_value()) - { - NpcCustomer->WriteCreate(data, receiver, owner); - } - if (OutputItem.has_value()) - { - OutputItem->WriteCreate(data, receiver, owner); - } - if (OutputItemData.has_value()) - { - data << *OutputItemData; - } - data.FlushBits(); -} - -void CraftingOrderData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 26); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreChangesMask) - Reagents.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Reagents.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < Reagents.size(); ++i) - { - if (Reagents.HasChanged(i) || ignoreChangesMask) - { - Reagents[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - data << int32(Field_0); - } - if (changesMask[3]) - { - data << uint64(OrderID); - } - if (changesMask[4]) - { - data << int32(SkillLineAbilityID); - } - if (changesMask[5]) - { - data << int32(OrderState); - } - } - if (changesMask[6]) - { - if (changesMask[7]) - { - data << uint8(OrderType); - } - if (changesMask[8]) - { - data << uint8(MinQuality); - } - if (changesMask[9]) - { - data << int64(ExpirationTime); - } - if (changesMask[10]) - { - data << int64(ClaimEndTime); - } - if (changesMask[11]) - { - data << int64(TipAmount); - } - } - if (changesMask[12]) - { - if (changesMask[13]) - { - data << int64(ConsortiumCut); - } - if (changesMask[14]) - { - data << uint32(Flags); - } - if (changesMask[15]) - { - data << *CrafterGUID; - } - if (changesMask[16]) - { - data << *PersonalCrafterGUID; - } - if (changesMask[17]) - { - data << int32(NpcCraftingOrderSetID); - } - } - if (changesMask[18]) - { - if (changesMask[19]) - { - data << int32(NpcTreasureID); - } - if (changesMask[20]) - { - data.WriteBits(CustomerNotes->size(), 10); - } - data.WriteBits(Customer.has_value(), 1); - data.WriteBits(NpcCustomer.has_value(), 1); - data.WriteBits(OutputItem.has_value(), 1); - } - if (changesMask[24]) - { - data.WriteBits(OutputItemData.has_value(), 1); - } - if (changesMask[18]) - { - if (changesMask[20]) - { - data << WorldPackets::SizedString::Data(*CustomerNotes); - } - if (changesMask[21]) - { - if (Customer.has_value()) - { - Customer->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - if (changesMask[22]) - { - if (NpcCustomer.has_value()) - { - NpcCustomer->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - if (changesMask[23]) - { - if (OutputItem.has_value()) - { - OutputItem->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - } - if (changesMask[24]) - { - if (changesMask[25]) - { - if (OutputItemData.has_value()) - { - data << *OutputItemData; - } - } - } - data.FlushBits(); -} - -void CraftingOrderData::ClearChangesMask() -{ - Base::ClearChangesMask(Reagents); - Base::ClearChangesMask(Field_0); - Base::ClearChangesMask(OrderID); - Base::ClearChangesMask(SkillLineAbilityID); - Base::ClearChangesMask(OrderState); - Base::ClearChangesMask(OrderType); - Base::ClearChangesMask(MinQuality); - Base::ClearChangesMask(ExpirationTime); - Base::ClearChangesMask(ClaimEndTime); - Base::ClearChangesMask(TipAmount); - Base::ClearChangesMask(ConsortiumCut); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(CrafterGUID); - Base::ClearChangesMask(PersonalCrafterGUID); - Base::ClearChangesMask(NpcCraftingOrderSetID); - Base::ClearChangesMask(NpcTreasureID); - Base::ClearChangesMask(CustomerNotes); - Base::ClearChangesMask(Customer); - Base::ClearChangesMask(NpcCustomer); - Base::ClearChangesMask(OutputItem); - Base::ClearChangesMask(OutputItemData); - _changesMask.ResetAll(); -} - -void CraftingOrder::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Data->WriteCreate(data, receiver, owner); - data.WriteBits(RecraftItemInfo.has_value(), 1); - data.WriteBits(Enchantments.size(), 4); - data.WriteBits(Gems.size(), 2); - data.FlushBits(); - if (RecraftItemInfo.has_value()) - { - data << *RecraftItemInfo; - } - for (uint32 i = 0; i < Enchantments.size(); ++i) + void CraftingOrderItem::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const { - data << Enchantments[i]; - } - for (uint32 i = 0; i < Gems.size(); ++i) - { - data << Gems[i]; - } - data.FlushBits(); -} - -void CraftingOrder::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - if (changesMask[0]) - { - if (!ignoreChangesMask) - Enchantments.WriteUpdateMask(data, 4); - else - WriteCompleteDynamicFieldUpdateMask(Enchantments.size(), data, 4); - } - if (changesMask[1]) - { - if (!ignoreChangesMask) - Gems.WriteUpdateMask(data, 2); - else - WriteCompleteDynamicFieldUpdateMask(Gems.size(), data, 2); - } - data.FlushBits(); - if (changesMask[0]) - { - for (uint32 i = 0; i < Enchantments.size(); ++i) - { - if (Enchantments.HasChanged(i) || ignoreChangesMask) - { - data << Enchantments[i]; - } - } - } - if (changesMask[1]) - { - for (uint32 i = 0; i < Gems.size(); ++i) - { - if (Gems.HasChanged(i) || ignoreChangesMask) - { - data << Gems[i]; - } - } - } - if (changesMask[2]) - { - Data->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - data.WriteBits(RecraftItemInfo.has_value(), 1); - data.FlushBits(); - if (changesMask[3]) - { - if (RecraftItemInfo.has_value()) - { - data << *RecraftItemInfo; - } - } - data.FlushBits(); -} - -void CraftingOrder::ClearChangesMask() -{ - Base::ClearChangesMask(Enchantments); - Base::ClearChangesMask(Gems); - Base::ClearChangesMask(Data); - Base::ClearChangesMask(RecraftItemInfo); - _changesMask.ResetAll(); -} - -void PersonalCraftingOrderCount::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(ProfessionID); - data << uint32(Count); -} - -void PersonalCraftingOrderCount::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 2); - - data.FlushBits(); - if (changesMask[0]) - { - data << int32(ProfessionID); - } - if (changesMask[1]) - { - data << uint32(Count); - } -} - -void PersonalCraftingOrderCount::ClearChangesMask() -{ - Base::ClearChangesMask(ProfessionID); - Base::ClearChangesMask(Count); - _changesMask.ResetAll(); -} - -void NPCCraftingOrderInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint64(OrderID); - data << int32(NpcCraftingOrderSetID); - data << int32(NpcTreasureID); - data << int32(NpcCraftingOrderCustomerID); -} - -void NPCCraftingOrderInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - data << uint64(OrderID); - } - if (changesMask[1]) - { - data << int32(NpcCraftingOrderSetID); - } - if (changesMask[2]) - { - data << int32(NpcTreasureID); - } - if (changesMask[3]) - { - data << int32(NpcCraftingOrderCustomerID); - } -} - -void NPCCraftingOrderInfo::ClearChangesMask() -{ - Base::ClearChangesMask(OrderID); - Base::ClearChangesMask(NpcCraftingOrderSetID); - Base::ClearChangesMask(NpcTreasureID); - Base::ClearChangesMask(NpcCraftingOrderCustomerID); - _changesMask.ResetAll(); -} - -void CategoryCooldownMod::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellCategoryID); - data << int32(ModCooldown); -} - -void CategoryCooldownMod::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellCategoryID); - data << int32(ModCooldown); -} - -bool CategoryCooldownMod::operator==(CategoryCooldownMod const& right) const -{ - return SpellCategoryID == right.SpellCategoryID - && ModCooldown == right.ModCooldown; -} - -void WeeklySpellUse::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellCategoryID); - data << uint8(Uses); -} - -void WeeklySpellUse::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(SpellCategoryID); - data << uint8(Uses); -} - -bool WeeklySpellUse::operator==(WeeklySpellUse const& right) const -{ - return SpellCategoryID == right.SpellCategoryID - && Uses == right.Uses; -} + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); -void StablePetInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(PetSlot); - data << uint32(PetNumber); - data << uint32(CreatureID); - data << uint32(DisplayID); - data << uint32(ExperienceLevel); - data << uint8(PetFlags); - data << uint32(Specialization); - data.WriteBits(Name->size(), 8); - data << WorldPackets::SizedString::Data(*Name); - data.FlushBits(); -} + data.WriteBits(changesMask.GetBlock(0), 7); -void StablePetInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 9); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << uint32(PetSlot); - } - if (changesMask[2]) - { - data << uint32(PetNumber); - } - if (changesMask[3]) - { - data << uint32(CreatureID); - } - if (changesMask[4]) - { - data << uint32(DisplayID); - } - if (changesMask[5]) - { - data << uint32(ExperienceLevel); - } - if (changesMask[7]) - { - data << uint8(PetFlags); - } - if (changesMask[8]) - { - data << uint32(Specialization); - } - if (changesMask[6]) - { - data.WriteBits(Name->size(), 8); - data << WorldPackets::SizedString::Data(*Name); - } - } - data.FlushBits(); -} - -void StablePetInfo::ClearChangesMask() -{ - Base::ClearChangesMask(PetSlot); - Base::ClearChangesMask(PetNumber); - Base::ClearChangesMask(CreatureID); - Base::ClearChangesMask(DisplayID); - Base::ClearChangesMask(ExperienceLevel); - Base::ClearChangesMask(Name); - Base::ClearChangesMask(PetFlags); - Base::ClearChangesMask(Specialization); - _changesMask.ResetAll(); -} - -void StableInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(Pets.size()); - data << *StableMaster; - for (uint32 i = 0; i < Pets.size(); ++i) - { - Pets[i].WriteCreate(data, receiver, owner); - } -} - -void StableInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreChangesMask) - Pets.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Pets.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < Pets.size(); ++i) - { - if (Pets.HasChanged(i) || ignoreChangesMask) - { - Pets[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - data << *StableMaster; - } - } -} - -void StableInfo::ClearChangesMask() -{ - Base::ClearChangesMask(Pets); - Base::ClearChangesMask(StableMaster); - _changesMask.ResetAll(); -} - -void CollectableSourceTrackedData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(TargetType); - data << int32(TargetID); - data << int32(CollectableSourceInfoID); -} - -void CollectableSourceTrackedData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(TargetType); - } - if (changesMask[2]) - { - data << int32(TargetID); - } - if (changesMask[3]) - { - data << int32(CollectableSourceInfoID); - } - } -} - -void CollectableSourceTrackedData::ClearChangesMask() -{ - Base::ClearChangesMask(TargetType); - Base::ClearChangesMask(TargetID); - Base::ClearChangesMask(CollectableSourceInfoID); - _changesMask.ResetAll(); -} - -void BankTabSettings::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data.WriteBits(Name->size(), 7); - data.WriteBits(Icon->size(), 9); - data.WriteBits(Description->size(), 14); - data << int32(DepositFlags); - data << WorldPackets::SizedString::Data(*Name); - data << WorldPackets::SizedString::Data(*Icon); - data << WorldPackets::SizedString::Data(*Description); - data.FlushBits(); -} - -void BankTabSettings::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - if (changesMask[0]) - { - data.WriteBits(Name->size(), 7); - } - if (changesMask[1]) - { - data.WriteBits(Icon->size(), 9); - } - if (changesMask[2]) - { - data.WriteBits(Description->size(), 14); - } - data.FlushBits(); - if (changesMask[3]) - { - data << int32(DepositFlags); - } - if (changesMask[0]) - { - data << WorldPackets::SizedString::Data(*Name); - } - if (changesMask[1]) - { - data << WorldPackets::SizedString::Data(*Icon); - } - if (changesMask[2]) - { - data << WorldPackets::SizedString::Data(*Description); - } - data.FlushBits(); -} - -void BankTabSettings::ClearChangesMask() -{ - Base::ClearChangesMask(Name); - Base::ClearChangesMask(Icon); - Base::ClearChangesMask(Description); - Base::ClearChangesMask(DepositFlags); - _changesMask.ResetAll(); -} - -void WalkInData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(MapID); - data << int64(Field_8); - data << Field_18; - data.WriteBits(Type, 1); - data.FlushBits(); -} - -void WalkInData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(MapID); - data << int64(Field_8); - data << Field_18; - data.WriteBits(Type, 1); - data.FlushBits(); -} - -bool WalkInData::operator==(WalkInData const& right) const -{ - return MapID == right.MapID - && Field_8 == right.Field_8 - && Type == right.Type - && Field_18 == right.Field_18; -} - -void DelveData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << uint64(Field_8); - data << int32(Field_10); - data << int32(SpellID); - data << uint32(Owners.size()); - for (uint32 i = 0; i < Owners.size(); ++i) - { - data << Owners[i]; - } - data.WriteBits(Started, 1); - data.FlushBits(); -} - -void DelveData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data.FlushBits(); - data << int32(Field_0); - data << uint64(Field_8); - data << int32(Field_10); - data << int32(SpellID); - data << uint32(Owners.size()); - for (uint32 i = 0; i < Owners.size(); ++i) - { - data << Owners[i]; - } - data.WriteBits(Started, 1); - data.FlushBits(); -} - -bool DelveData::operator==(DelveData const& right) const -{ - return Owners == right.Owners - && Field_0 == right.Field_0 - && Field_8 == right.Field_8 - && Field_10 == right.Field_10 - && SpellID == right.SpellID - && Started == right.Started; -} - -void ChallengeModeData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(MapID); - data << int32(InitialPlayerCount); - data << uint64(InstanceID); - data << int64(StartTime); - data << KeystoneOwnerGUID; - data << LeaverGUID; - data << int64(InstanceAbandonVoteCooldown); - data.WriteBits(IsActive, 1); - data.WriteBits(HasRestrictions, 1); - data.WriteBits(CanVoteAbandon, 1); - data.FlushBits(); -} - -void ChallengeModeData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(MapID); - data << int32(InitialPlayerCount); - data << uint64(InstanceID); - data << int64(StartTime); - data << KeystoneOwnerGUID; - data << LeaverGUID; - data << int64(InstanceAbandonVoteCooldown); - data.WriteBits(IsActive, 1); - data.WriteBits(HasRestrictions, 1); - data.WriteBits(CanVoteAbandon, 1); - data.FlushBits(); -} - -bool ChallengeModeData::operator==(ChallengeModeData const& right) const -{ - return MapID == right.MapID - && InitialPlayerCount == right.InitialPlayerCount - && InstanceID == right.InstanceID - && StartTime == right.StartTime - && KeystoneOwnerGUID == right.KeystoneOwnerGUID - && LeaverGUID == right.LeaverGUID - && InstanceAbandonVoteCooldown == right.InstanceAbandonVoteCooldown - && IsActive == right.IsActive - && HasRestrictions == right.HasRestrictions - && CanVoteAbandon == right.CanVoteAbandon; -} - -void TransmogOutfitDataInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint8(SetType); - data << uint32(Icon); - data.WriteBits(Name->size(), 8); - data.WriteBit(SituationsEnabled); - data.FlushBits(); - data << WorldPackets::SizedString::Data(*Name); - data.FlushBits(); -} - -void TransmogOutfitDataInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - if (changesMask[0]) - { - data.WriteBit(SituationsEnabled); - } - data.FlushBits(); - if (changesMask[1]) - { - data << uint8(SetType); - } - if (changesMask[3]) - { - data << uint32(Icon); - } - if (changesMask[2]) - { - data.WriteBits(Name->size(), 8); - data << WorldPackets::SizedString::Data(*Name); - } - data.FlushBits(); -} - -void TransmogOutfitDataInfo::ClearChangesMask() -{ - Base::ClearChangesMask(SituationsEnabled); - Base::ClearChangesMask(SetType); - Base::ClearChangesMask(Name); - Base::ClearChangesMask(Icon); - _changesMask.ResetAll(); -} - -void TransmogOutfitSituationInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(SituationID); - data << uint32(SpecID); - data << uint32(LoadoutID); - data << uint32(EquipmentSetID); -} - -void TransmogOutfitSituationInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - data << uint32(SituationID); - } - if (changesMask[1]) - { - data << uint32(SpecID); - } - if (changesMask[2]) - { - data << uint32(LoadoutID); - } - if (changesMask[3]) - { - data << uint32(EquipmentSetID); - } -} - -void TransmogOutfitSituationInfo::ClearChangesMask() -{ - Base::ClearChangesMask(SituationID); - Base::ClearChangesMask(SpecID); - Base::ClearChangesMask(LoadoutID); - Base::ClearChangesMask(EquipmentSetID); - _changesMask.ResetAll(); -} - -void TransmogOutfitSlotData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int8(Slot); - data << uint8(SlotOption); - data << uint32(ItemModifiedAppearanceID); - data << uint8(AppearanceDisplayType); - data << uint32(SpellItemEnchantmentID); - data << uint8(IllusionDisplayType); - data << uint32(Flags); -} - -void TransmogOutfitSlotData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 7); - - data.FlushBits(); - if (changesMask[0]) - { - data << int8(Slot); - } - if (changesMask[1]) - { - data << uint8(SlotOption); - } - if (changesMask[2]) - { - data << uint32(ItemModifiedAppearanceID); - } - if (changesMask[3]) - { - data << uint8(AppearanceDisplayType); - } - if (changesMask[4]) - { - data << uint32(SpellItemEnchantmentID); - } - if (changesMask[5]) - { - data << uint8(IllusionDisplayType); - } - if (changesMask[6]) - { - data << uint32(Flags); - } -} - -void TransmogOutfitSlotData::ClearChangesMask() -{ - Base::ClearChangesMask(Slot); - Base::ClearChangesMask(SlotOption); - Base::ClearChangesMask(ItemModifiedAppearanceID); - Base::ClearChangesMask(AppearanceDisplayType); - Base::ClearChangesMask(SpellItemEnchantmentID); - Base::ClearChangesMask(IllusionDisplayType); - Base::ClearChangesMask(Flags); - _changesMask.ResetAll(); -} - -void TransmogOutfitData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(Id); - data << uint32(Situations.size()); - data << uint32(Slots.size()); - data << uint32(Flags); - for (uint32 i = 0; i < Situations.size(); ++i) - { - Situations[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < Slots.size(); ++i) - { - Slots[i].WriteCreate(data, receiver, owner); - } - OutfitInfo->WriteCreate(data, receiver, owner); -} - -void TransmogOutfitData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 5); - - if (changesMask[0]) - { - if (!ignoreChangesMask) - Situations.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Situations.size(), data); - } - if (changesMask[1]) - { - if (!ignoreChangesMask) - Slots.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Slots.size(), data); - } - data.FlushBits(); - if (changesMask[0]) - { - for (uint32 i = 0; i < Situations.size(); ++i) - { - if (Situations.HasChanged(i) || ignoreChangesMask) - { - Situations[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - } - if (changesMask[1]) - { - for (uint32 i = 0; i < Slots.size(); ++i) - { - if (Slots.HasChanged(i) || ignoreChangesMask) - { - Slots[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - data << uint32(Id); - } - if (changesMask[4]) - { - data << uint32(Flags); - } - if (changesMask[3]) - { - OutfitInfo->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } -} - -void TransmogOutfitData::ClearChangesMask() -{ - Base::ClearChangesMask(Situations); - Base::ClearChangesMask(Slots); - Base::ClearChangesMask(Id); - Base::ClearChangesMask(OutfitInfo); - Base::ClearChangesMask(Flags); - _changesMask.ResetAll(); -} - -void TransmogOutfitMetadata::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint8(SituationTrigger); - data << uint32(TransmogOutfitID); - data << uint8(StampedOptionMainHand); - data << uint8(StampedOptionOffHand); - data << float(CostMod); - data.WriteBit(Locked); - data.FlushBits(); -} - -void TransmogOutfitMetadata::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint8(SituationTrigger); - data << uint32(TransmogOutfitID); - data << uint8(StampedOptionMainHand); - data << uint8(StampedOptionOffHand); - data << float(CostMod); - data.WriteBit(Locked); - data.FlushBits(); - data.FlushBits(); -} - -bool TransmogOutfitMetadata::operator==(TransmogOutfitMetadata const& right) const -{ - return Locked == right.Locked - && SituationTrigger == right.SituationTrigger - && TransmogOutfitID == right.TransmogOutfitID - && StampedOptionMainHand == right.StampedOptionMainHand - && StampedOptionOffHand == right.StampedOptionOffHand - && CostMod == right.CostMod; -} - -void Research::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int16(ResearchProjectID); -} - -void Research::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int16(ResearchProjectID); -} - -bool Research::operator==(Research const& right) const -{ - return ResearchProjectID == right.ResearchProjectID; -} - -void ActivePlayerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - for (uint32 i = 0; i < 105; ++i) - { - data << InvSlots[i]; - } - data << *FarsightObject; - data << *SummonedBattlePetGUID; - data << uint32(KnownTitles.size()); - data << uint64(Coinage); - data << uint64(AccountBankCoinage); - data << int32(XP); - data << int32(NextLevelXP); - data << int32(TrialXP); - Skill->WriteCreate(data, receiver, owner); - data << int32(CharacterPoints); - data << int32(MaxTalentTiers); - data << uint32(TrackCreatureMask); - data << float(MainhandExpertise); - data << float(OffhandExpertise); - data << float(RangedExpertise); - data << float(CombatRatingExpertise); - data << float(BlockPercentage); - data << float(DodgePercentage); - data << float(DodgePercentageFromAttribute); - data << float(ParryPercentage); - data << float(ParryPercentageFromAttribute); - data << float(CritPercentage); - data << float(RangedCritPercentage); - data << float(OffhandCritPercentage); - data << float(SpellCritPercentage); - data << int32(ShieldBlock); - data << float(ShieldBlockCritPercentage); - data << float(Mastery); - data << float(Speed); - data << float(Avoidance); - data << float(Sturdiness); - data << int32(Versatility); - data << float(VersatilityBonus); - data << float(PvpPowerDamage); - data << float(PvpPowerHealing); - BitVectors->WriteCreate(data, receiver, owner); - data << uint32(CharacterDataElements.size()); - data << uint32(AccountDataElements.size()); - for (uint32 i = 0; i < 2; ++i) - { - RestInfo[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < 7; ++i) - { - data << int32(ModDamageDonePos[i]); - data << int32(ModDamageDoneNeg[i]); - data << float(ModDamageDonePercent[i]); - data << float(ModHealingDonePercent[i]); - } - data << int32(ModHealingDonePos); - data << float(ModHealingPercent); - data << float(ModPeriodicHealingDonePercent); - for (uint32 i = 0; i < 3; ++i) - { - data << float(WeaponDmgMultipliers[i]); - data << float(WeaponAtkSpeedMultipliers[i]); - } - data << float(ModSpellPowerPercent); - data << float(ModResiliencePercent); - data << float(OverrideSpellPowerByAPPercent); - data << float(OverrideAPBySpellPowerPercent); - data << int32(ModTargetResistance); - data << int32(ModTargetPhysicalResistance); - data << uint32(LocalFlags); - data << uint8(GrantableLevels); - data << uint8(MultiActionBars); - data << uint8(LifetimeMaxRank); - data << uint8(NumRespecs); - data << uint32(PvpMedals); - for (uint32 i = 0; i < 12; ++i) - { - data << uint32(BuybackPrice[i]); - data << int64(BuybackTimestamp[i]); - } - data << uint16(TodayHonorableKills); - data << uint16(YesterdayHonorableKills); - data << uint32(LifetimeHonorableKills); - data << int32(WatchedFactionIndex); - for (uint32 i = 0; i < 32; ++i) - { - data << int32(CombatRatings[i]); - } - data << uint32(PvpInfo.size()); - data << int32(MaxLevel); - data << int32(ScalingPlayerLevelDelta); - data << int32(MaxCreatureScalingLevel); - data << uint8(TransmogCostMinScalingLevel); - for (uint32 i = 0; i < 4; ++i) - { - data << uint32(NoReagentCostMask[i]); - } - data << int32(PetSpellPower); - for (uint32 i = 0; i < 2; ++i) - { - data << int32(ProfessionSkillLine[i]); - } - data << float(UiHitModifier); - data << float(UiSpellHitModifier); - data << int32(HomeRealmTimeOffset); - data << float(ModPetHaste); - data << int8(JailersTowerLevelMax); - data << int8(JailersTowerLevel); - data << uint8(LocalRegenFlags); - data << uint8(AuraVision); - data << uint8(NumBackpackSlots); - data << int32(OverrideSpellsID); - data << uint16(LootSpecID); - data << uint32(OverrideZonePVPType); - for (uint32 i = 0; i < 5; ++i) - { - data << uint32(BagSlotFlags[i]); - } - data << int32(Honor); - data << int32(HonorNextLevel); - data << int32(PerksProgramCurrency); - data << uint8(NumBankSlots); - data << uint8(NumCharacterBankTabs); - data << uint8(NumAccountBankTabs); - for (uint32 i = 0; i < 1; ++i) - { - data << uint32(ResearchSites[i].size()); - data << uint32(ResearchSiteProgress[i].size()); - data << uint32(Research[i].size()); - for (uint32 j = 0; j < ResearchSites[i].size(); ++j) - { - data << uint16(ResearchSites[i][j]); - } - for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) - { - data << uint32(ResearchSiteProgress[i][j]); - } - for (uint32 j = 0; j < Research[i].size(); ++j) - { - Research[i][j].WriteCreate(data, receiver, owner); - } - } - data << uint32(DailyQuestsCompleted.size()); - data << uint32(Field_1328.size()); - data << uint32(AvailableQuestLineXQuestIDs.size()); - data << uint32(Heirlooms.size()); - data << uint32(HeirloomFlags.size()); - data << uint32(Toys.size()); - data << uint32(ToyFlags.size()); - data << uint32(Transmog.size()); - data << uint32(ConditionalTransmog.size()); - data << uint32(SelfResSpells.size()); - data << uint32(RuneforgePowers.size()); - data << uint32(TransmogIllusions.size()); - data << uint32(WarbandScenes.size()); - data << uint32(HouseRooms.size()); - data << uint32(HouseExteriorComponents.size()); - data << uint32(HouseThemes.size()); - data << uint32(HouseRoomComponentTextures.size()); - data << uint32(HouseTypes.size()); - data << uint32(Field_1980.size()); - data << uint32(CharacterRestrictions.size()); - data << uint32(SpellPctModByLabel.size()); - data << uint32(SpellFlatModByLabel.size()); - data << uint32(SpellPctModPVPByLabel.size()); - data << uint32(SpellFlatModPVPByLabel.size()); - data << uint32(MawPowers.size()); - data << uint32(MultiFloorExploration.size()); - data << uint32(RecipeProgression.size()); - data << uint32(ReplayedQuests.size()); - data << uint32(TaskQuests.size()); - data << uint32(DisabledSpells.size()); - data << int32(UiChromieTimeExpansionID); - data << int32(TimerunningSeasonID); - data << int32(TransportServerTime); - data << uint32(WeeklyRewardsPeriodSinceOrigin); - data << int16(DEBUGSoulbindConduitRank); - data << uint32(ActiveCombatTraitConfigID); - data << uint32(CraftingOrders.size()); - data << uint32(PersonalCraftingOrderCounts.size()); - data << uint32(NpcCraftingOrders.size()); - data << uint32(CategoryCooldownMods.size()); - data << uint32(WeeklySpellUses.size()); - for (uint32 i = 0; i < 17; ++i) - { - data << float(ItemUpgradeHighWatermark[i]); - } - data << int32(ItemUpgradeHighOnehandWeaponItemID); - data << int32(ItemUpgradeHighFingerItemID); - data << float(ItemUpgradeHighFingerWatermark); - data << int32(ItemUpgradeHighTrinketItemID); - data << float(ItemUpgradeHighTrinketWatermark); - data << uint64(LootHistoryInstanceID); - data << uint32(TrackedCollectableSources.size()); - data << uint8(RequiredMountCapabilityFlags); - for (uint32 i = 0; i < KnownTitles.size(); ++i) - { - data << uint64(KnownTitles[i]); - } - for (uint32 i = 0; i < CharacterDataElements.size(); ++i) - { - CharacterDataElements[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < AccountDataElements.size(); ++i) - { - AccountDataElements[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i) - { - data << int32(DailyQuestsCompleted[i]); - } - for (uint32 i = 0; i < Field_1328.size(); ++i) - { - data << int32(Field_1328[i]); - } - for (uint32 i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i) - { - data << int32(AvailableQuestLineXQuestIDs[i]); - } - for (uint32 i = 0; i < Heirlooms.size(); ++i) - { - data << int32(Heirlooms[i]); - } - for (uint32 i = 0; i < HeirloomFlags.size(); ++i) - { - data << uint32(HeirloomFlags[i]); - } - for (uint32 i = 0; i < Toys.size(); ++i) - { - data << int32(Toys[i]); - } - for (uint32 i = 0; i < ToyFlags.size(); ++i) - { - data << uint32(ToyFlags[i]); - } - for (uint32 i = 0; i < Transmog.size(); ++i) - { - data << uint32(Transmog[i]); - } - for (uint32 i = 0; i < ConditionalTransmog.size(); ++i) - { - data << int32(ConditionalTransmog[i]); - } - for (uint32 i = 0; i < SelfResSpells.size(); ++i) - { - data << int32(SelfResSpells[i]); - } - for (uint32 i = 0; i < RuneforgePowers.size(); ++i) - { - data << uint32(RuneforgePowers[i]); - } - for (uint32 i = 0; i < TransmogIllusions.size(); ++i) - { - data << uint32(TransmogIllusions[i]); - } - for (uint32 i = 0; i < WarbandScenes.size(); ++i) - { - data << uint32(WarbandScenes[i]); - } - for (uint32 i = 0; i < HouseRooms.size(); ++i) - { - data << uint32(HouseRooms[i]); - } - for (uint32 i = 0; i < HouseExteriorComponents.size(); ++i) - { - data << uint32(HouseExteriorComponents[i]); - } - for (uint32 i = 0; i < HouseThemes.size(); ++i) - { - data << uint32(HouseThemes[i]); - } - for (uint32 i = 0; i < HouseRoomComponentTextures.size(); ++i) - { - data << uint32(HouseRoomComponentTextures[i]); - } - for (uint32 i = 0; i < HouseTypes.size(); ++i) - { - data << uint32(HouseTypes[i]); - } - for (uint32 i = 0; i < Field_1980.size(); ++i) - { - data << int32(Field_1980[i]); - } - for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) - { - SpellPctModByLabel[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) - { - SpellFlatModByLabel[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < SpellPctModPVPByLabel.size(); ++i) - { - SpellPctModPVPByLabel[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < SpellFlatModPVPByLabel.size(); ++i) - { - SpellFlatModPVPByLabel[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < MawPowers.size(); ++i) - { - MawPowers[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) - { - MultiFloorExploration[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < RecipeProgression.size(); ++i) - { - RecipeProgression[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < ReplayedQuests.size(); ++i) - { - ReplayedQuests[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < TaskQuests.size(); ++i) - { - TaskQuests[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < DisabledSpells.size(); ++i) - { - data << int32(DisabledSpells[i]); - } - for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) - { - PersonalCraftingOrderCounts[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i) - { - NpcCraftingOrders[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) - { - CategoryCooldownMods[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) - { - WeeklySpellUses[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) - { - TrackedCollectableSources[i].WriteCreate(data, receiver, owner); - } - data.FlushBits(); - data.WriteBit(BackpackAutoSortDisabled); - data.WriteBit(BackpackSellJunkDisabled); - data.WriteBit(BankAutoSortDisabled); - data.WriteBit(SortBagsRightToLeft); - data.WriteBit(InsertItemsLeftToRight); - data.WriteBit(HasPerksProgramPendingReward); - data.WriteBits(QuestSession.has_value(), 1); - data.WriteBits(PetStable.has_value(), 1); - data.WriteBits(CharacterBankTabSettings.size(), 3); - data.WriteBits(AccountBankTabSettings.size(), 3); - data.WriteBits(WalkInData.has_value(), 1); - data.WriteBits(DelveData.has_value(), 1); - data.WriteBits(ChallengeModeData.has_value(), 1); - data.FlushBits(); - ResearchHistory->WriteCreate(data, receiver, owner); - if (QuestSession.has_value()) - { - QuestSession->WriteCreate(data, receiver, owner); - } - data << *FrozenPerksVendorItem; - LevelLinkInfo->WriteCreate(data, receiver, owner); - data << *DungeonScore; - WriteMapFieldCreate(TraitConfigs, data, receiver, owner); - WriteMapFieldCreate(TransmogOutfits, data, receiver, owner); - ViewedOutfit->WriteCreate(data, receiver, owner); - TransmogMetadata->WriteCreate(data, receiver, owner); - for (uint32 i = 0; i < PvpInfo.size(); ++i) - { - PvpInfo[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) - { - CharacterRestrictions[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < CraftingOrders.size(); ++i) - { - CraftingOrders[i].WriteCreate(data, receiver, owner); - } - if (PetStable.has_value()) - { - PetStable->WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) - { - CharacterBankTabSettings[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) - { - AccountBankTabSettings[i].WriteCreate(data, receiver, owner); - } - if (WalkInData.has_value()) - { - WalkInData->WriteCreate(data, receiver, owner); - } - if (DelveData.has_value()) - { - DelveData->WriteCreate(data, receiver, owner); - } - if (ChallengeModeData.has_value()) - { - ChallengeModeData->WriteCreate(data, receiver, owner); - } - data.FlushBits(); -} - -void ActivePlayerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void ActivePlayerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 13); - for (uint32 i = 0; i < 13; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(BackpackAutoSortDisabled); - } - if (changesMask[2]) - { - data.WriteBit(BackpackSellJunkDisabled); - } - if (changesMask[3]) - { - data.WriteBit(BankAutoSortDisabled); - } - if (changesMask[4]) - { - data.WriteBit(SortBagsRightToLeft); - } - if (changesMask[5]) - { - data.WriteBit(InsertItemsLeftToRight); - } - if (changesMask[6]) - { - data.WriteBit(HasPerksProgramPendingReward); - } - if (changesMask[7]) - { - if (!ignoreNestedChangesMask) - KnownTitles.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(KnownTitles.size(), data); - } - if (changesMask[8]) - { - if (!ignoreNestedChangesMask) - CharacterDataElements.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CharacterDataElements.size(), data); - } - if (changesMask[9]) - { - if (!ignoreNestedChangesMask) - AccountDataElements.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(AccountDataElements.size(), data); - } - if (changesMask[10]) - { - if (!ignoreNestedChangesMask) - PvpInfo.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data); - } - } - if (changesMask[50]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[51]) - { - if (!ignoreNestedChangesMask) - ResearchSites[i].WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ResearchSites[i].size(), data); - } - } - } - if (changesMask[52]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[53]) - { - if (!ignoreNestedChangesMask) - ResearchSiteProgress[i].WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress[i].size(), data); - } - } - } - if (changesMask[54]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[55]) - { - if (!ignoreNestedChangesMask) - Research[i].WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Research[i].size(), data); - } - } - } - if (changesMask[50]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[51]) - { - for (uint32 j = 0; j < ResearchSites[i].size(); ++j) - { - if (ResearchSites[i].HasChanged(j) || ignoreNestedChangesMask) - { - data << uint16(ResearchSites[i][j]); - } - } - } - } - } - if (changesMask[52]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[53]) - { - for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) - { - if (ResearchSiteProgress[i].HasChanged(j) || ignoreNestedChangesMask) - { - data << uint32(ResearchSiteProgress[i][j]); - } - } - } - } - } - if (changesMask[54]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[55]) - { - for (uint32 j = 0; j < Research[i].size(); ++j) - { - if (Research[i].HasChanged(j) || ignoreNestedChangesMask) - { - Research[i][j].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[11]) - { - if (!ignoreNestedChangesMask) - DailyQuestsCompleted.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.size(), data); - } - if (changesMask[12]) - { - if (!ignoreNestedChangesMask) - Field_1328.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Field_1328.size(), data); - } - if (changesMask[13]) - { - if (!ignoreNestedChangesMask) - AvailableQuestLineXQuestIDs.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.size(), data); - } - if (changesMask[14]) - { - if (!ignoreNestedChangesMask) - Heirlooms.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Heirlooms.size(), data); - } - if (changesMask[15]) - { - if (!ignoreNestedChangesMask) - HeirloomFlags.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.size(), data); - } - if (changesMask[16]) - { - if (!ignoreNestedChangesMask) - Toys.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Toys.size(), data); - } - if (changesMask[17]) - { - if (!ignoreNestedChangesMask) - ToyFlags.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ToyFlags.size(), data); - } - if (changesMask[18]) - { - if (!ignoreNestedChangesMask) - Transmog.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Transmog.size(), data); - } - if (changesMask[19]) - { - if (!ignoreNestedChangesMask) - ConditionalTransmog.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.size(), data); - } - if (changesMask[20]) - { - if (!ignoreNestedChangesMask) - SelfResSpells.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SelfResSpells.size(), data); - } - if (changesMask[21]) - { - if (!ignoreNestedChangesMask) - RuneforgePowers.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.size(), data); - } - if (changesMask[22]) - { - if (!ignoreNestedChangesMask) - TransmogIllusions.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.size(), data); - } - if (changesMask[23]) - { - if (!ignoreNestedChangesMask) - WarbandScenes.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(WarbandScenes.size(), data); - } - if (changesMask[24]) - { - if (!ignoreNestedChangesMask) - HouseRooms.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HouseRooms.size(), data); - } - if (changesMask[25]) - { - if (!ignoreNestedChangesMask) - HouseExteriorComponents.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HouseExteriorComponents.size(), data); - } - if (changesMask[26]) - { - if (!ignoreNestedChangesMask) - HouseThemes.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HouseThemes.size(), data); - } - if (changesMask[27]) - { - if (!ignoreNestedChangesMask) - HouseRoomComponentTextures.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HouseRoomComponentTextures.size(), data); - } - if (changesMask[28]) - { - if (!ignoreNestedChangesMask) - HouseTypes.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HouseTypes.size(), data); - } - if (changesMask[29]) - { - if (!ignoreNestedChangesMask) - Field_1980.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Field_1980.size(), data); - } - if (changesMask[30]) - { - if (!ignoreNestedChangesMask) - CharacterRestrictions.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data); - } - if (changesMask[31]) - { - if (!ignoreNestedChangesMask) - SpellPctModByLabel.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data); - } - } - if (changesMask[32]) - { - if (changesMask[33]) - { - if (!ignoreNestedChangesMask) - SpellFlatModByLabel.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data); - } - if (changesMask[34]) - { - if (!ignoreNestedChangesMask) - SpellPctModPVPByLabel.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SpellPctModPVPByLabel.size(), data); - } - if (changesMask[35]) - { - if (!ignoreNestedChangesMask) - SpellFlatModPVPByLabel.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SpellFlatModPVPByLabel.size(), data); - } - if (changesMask[36]) - { - if (!ignoreNestedChangesMask) - MawPowers.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(MawPowers.size(), data); - } - if (changesMask[37]) - { - if (!ignoreNestedChangesMask) - MultiFloorExploration.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.size(), data); - } - if (changesMask[38]) - { - if (!ignoreNestedChangesMask) - RecipeProgression.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(RecipeProgression.size(), data); - } - if (changesMask[39]) - { - if (!ignoreNestedChangesMask) - ReplayedQuests.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data); - } - if (changesMask[40]) - { - if (!ignoreNestedChangesMask) - TaskQuests.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(TaskQuests.size(), data); - } - if (changesMask[41]) - { - if (!ignoreNestedChangesMask) - DisabledSpells.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data); - } - if (changesMask[42]) - { - if (!ignoreNestedChangesMask) - CraftingOrders.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data); - } - if (changesMask[43]) - { - if (!ignoreNestedChangesMask) - PersonalCraftingOrderCounts.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(PersonalCraftingOrderCounts.size(), data); - } - if (changesMask[44]) - { - if (!ignoreNestedChangesMask) - NpcCraftingOrders.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(NpcCraftingOrders.size(), data); - } - if (changesMask[45]) - { - if (!ignoreNestedChangesMask) - CategoryCooldownMods.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data); - } - if (changesMask[46]) - { - if (!ignoreNestedChangesMask) - WeeklySpellUses.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data); - } - if (changesMask[47]) - { - if (!ignoreNestedChangesMask) - TrackedCollectableSources.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(TrackedCollectableSources.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[7]) - { - for (uint32 i = 0; i < KnownTitles.size(); ++i) - { - if (KnownTitles.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint64(KnownTitles[i]); - } - } - } - if (changesMask[8]) - { - for (uint32 i = 0; i < CharacterDataElements.size(); ++i) - { - if (CharacterDataElements.HasChanged(i) || ignoreNestedChangesMask) - { - CharacterDataElements[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[9]) - { - for (uint32 i = 0; i < AccountDataElements.size(); ++i) - { - if (AccountDataElements.HasChanged(i) || ignoreNestedChangesMask) - { - AccountDataElements[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[11]) - { - for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i) - { - if (DailyQuestsCompleted.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(DailyQuestsCompleted[i]); - } - } - } - if (changesMask[12]) - { - for (uint32 i = 0; i < Field_1328.size(); ++i) - { - if (Field_1328.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(Field_1328[i]); - } - } - } - if (changesMask[13]) - { - for (uint32 i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i) - { - if (AvailableQuestLineXQuestIDs.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(AvailableQuestLineXQuestIDs[i]); - } - } - } - if (changesMask[14]) - { - for (uint32 i = 0; i < Heirlooms.size(); ++i) - { - if (Heirlooms.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(Heirlooms[i]); - } - } - } - if (changesMask[15]) - { - for (uint32 i = 0; i < HeirloomFlags.size(); ++i) - { - if (HeirloomFlags.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(HeirloomFlags[i]); - } - } - } - if (changesMask[16]) - { - for (uint32 i = 0; i < Toys.size(); ++i) - { - if (Toys.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(Toys[i]); - } - } - } - if (changesMask[17]) - { - for (uint32 i = 0; i < ToyFlags.size(); ++i) - { - if (ToyFlags.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(ToyFlags[i]); - } - } - } - if (changesMask[18]) - { - for (uint32 i = 0; i < Transmog.size(); ++i) - { - if (Transmog.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(Transmog[i]); - } - } - } - if (changesMask[19]) - { - for (uint32 i = 0; i < ConditionalTransmog.size(); ++i) - { - if (ConditionalTransmog.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(ConditionalTransmog[i]); - } - } - } - if (changesMask[20]) - { - for (uint32 i = 0; i < SelfResSpells.size(); ++i) - { - if (SelfResSpells.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(SelfResSpells[i]); - } - } - } - if (changesMask[21]) - { - for (uint32 i = 0; i < RuneforgePowers.size(); ++i) - { - if (RuneforgePowers.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(RuneforgePowers[i]); - } - } - } - if (changesMask[22]) - { - for (uint32 i = 0; i < TransmogIllusions.size(); ++i) - { - if (TransmogIllusions.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(TransmogIllusions[i]); - } - } - } - if (changesMask[23]) - { - for (uint32 i = 0; i < WarbandScenes.size(); ++i) - { - if (WarbandScenes.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(WarbandScenes[i]); - } - } - } - if (changesMask[24]) - { - for (uint32 i = 0; i < HouseRooms.size(); ++i) - { - if (HouseRooms.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(HouseRooms[i]); - } - } - } - if (changesMask[25]) - { - for (uint32 i = 0; i < HouseExteriorComponents.size(); ++i) - { - if (HouseExteriorComponents.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(HouseExteriorComponents[i]); - } - } - } - if (changesMask[26]) - { - for (uint32 i = 0; i < HouseThemes.size(); ++i) - { - if (HouseThemes.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(HouseThemes[i]); - } - } - } - if (changesMask[27]) - { - for (uint32 i = 0; i < HouseRoomComponentTextures.size(); ++i) - { - if (HouseRoomComponentTextures.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(HouseRoomComponentTextures[i]); - } - } - } - if (changesMask[28]) - { - for (uint32 i = 0; i < HouseTypes.size(); ++i) - { - if (HouseTypes.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(HouseTypes[i]); - } - } - } - if (changesMask[29]) - { - for (uint32 i = 0; i < Field_1980.size(); ++i) - { - if (Field_1980.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(Field_1980[i]); - } - } - } - if (changesMask[31]) - { - for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) - { - if (SpellPctModByLabel.HasChanged(i) || ignoreNestedChangesMask) - { - SpellPctModByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - } - if (changesMask[32]) - { - if (changesMask[33]) - { - for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) - { - if (SpellFlatModByLabel.HasChanged(i) || ignoreNestedChangesMask) - { - SpellFlatModByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[34]) - { - for (uint32 i = 0; i < SpellPctModPVPByLabel.size(); ++i) - { - if (SpellPctModPVPByLabel.HasChanged(i) || ignoreNestedChangesMask) - { - SpellPctModPVPByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[35]) - { - for (uint32 i = 0; i < SpellFlatModPVPByLabel.size(); ++i) - { - if (SpellFlatModPVPByLabel.HasChanged(i) || ignoreNestedChangesMask) - { - SpellFlatModPVPByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[36]) - { - for (uint32 i = 0; i < MawPowers.size(); ++i) - { - if (MawPowers.HasChanged(i) || ignoreNestedChangesMask) - { - MawPowers[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[37]) - { - for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) - { - if (MultiFloorExploration.HasChanged(i) || ignoreNestedChangesMask) - { - MultiFloorExploration[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[38]) - { - for (uint32 i = 0; i < RecipeProgression.size(); ++i) - { - if (RecipeProgression.HasChanged(i) || ignoreNestedChangesMask) - { - RecipeProgression[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[39]) - { - for (uint32 i = 0; i < ReplayedQuests.size(); ++i) - { - if (ReplayedQuests.HasChanged(i) || ignoreNestedChangesMask) - { - ReplayedQuests[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[40]) - { - for (uint32 i = 0; i < TaskQuests.size(); ++i) - { - if (TaskQuests.HasChanged(i) || ignoreNestedChangesMask) - { - TaskQuests[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[41]) - { - for (uint32 i = 0; i < DisabledSpells.size(); ++i) - { - if (DisabledSpells.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(DisabledSpells[i]); - } - } - } - if (changesMask[43]) - { - for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) - { - if (PersonalCraftingOrderCounts.HasChanged(i) || ignoreNestedChangesMask) - { - PersonalCraftingOrderCounts[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[44]) - { - for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i) - { - if (NpcCraftingOrders.HasChanged(i) || ignoreNestedChangesMask) - { - NpcCraftingOrders[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[45]) - { - for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) - { - if (CategoryCooldownMods.HasChanged(i) || ignoreNestedChangesMask) - { - CategoryCooldownMods[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[46]) - { - for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) - { - if (WeeklySpellUses.HasChanged(i) || ignoreNestedChangesMask) - { - WeeklySpellUses[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[47]) - { - for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) - { - if (TrackedCollectableSources.HasChanged(i) || ignoreNestedChangesMask) - { - TrackedCollectableSources[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - } - data.FlushBits(); - if (changesMask[32]) - { - if (changesMask[48]) - { - if (!ignoreNestedChangesMask) - CharacterBankTabSettings.WriteUpdateMask(data, 3); - else - WriteCompleteDynamicFieldUpdateMask(CharacterBankTabSettings.size(), data, 3); - } - if (changesMask[49]) - { - if (!ignoreNestedChangesMask) - AccountBankTabSettings.WriteUpdateMask(data, 3); - else - WriteCompleteDynamicFieldUpdateMask(AccountBankTabSettings.size(), data, 3); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[10]) - { - for (uint32 i = 0; i < PvpInfo.size(); ++i) - { - if (PvpInfo.HasChanged(i) || ignoreNestedChangesMask) - { - PvpInfo[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[30]) - { - for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) - { - if (CharacterRestrictions.HasChanged(i) || ignoreNestedChangesMask) - { - CharacterRestrictions[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - } - if (changesMask[32]) - { - if (changesMask[42]) - { - for (uint32 i = 0; i < CraftingOrders.size(); ++i) - { - if (CraftingOrders.HasChanged(i) || ignoreNestedChangesMask) - { - CraftingOrders[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[48]) - { - for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) - { - if (CharacterBankTabSettings.HasChanged(i) || ignoreNestedChangesMask) - { - CharacterBankTabSettings[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[49]) - { - for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) - { - if (AccountBankTabSettings.HasChanged(i) || ignoreNestedChangesMask) - { - AccountBankTabSettings[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[56]) - { - data << *FarsightObject; - } - if (changesMask[57]) - { - data << *SummonedBattlePetGUID; - } - if (changesMask[58]) - { - data << uint64(Coinage); - } - if (changesMask[59]) - { - data << uint64(AccountBankCoinage); - } - if (changesMask[60]) - { - data << int32(XP); - } - if (changesMask[61]) - { - data << int32(NextLevelXP); - } - if (changesMask[62]) - { - data << int32(TrialXP); - } - if (changesMask[63]) - { - Skill->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[64]) - { - data << int32(CharacterPoints); - } - if (changesMask[65]) - { - data << int32(MaxTalentTiers); - } - if (changesMask[66]) - { - data << uint32(TrackCreatureMask); - } - if (changesMask[67]) - { - data << float(MainhandExpertise); - } - if (changesMask[68]) - { - data << float(OffhandExpertise); - } - if (changesMask[69]) - { - data << float(RangedExpertise); - } - } - if (changesMask[70]) - { - if (changesMask[71]) - { - data << float(CombatRatingExpertise); - } - if (changesMask[72]) - { - data << float(BlockPercentage); - } - if (changesMask[73]) - { - data << float(DodgePercentage); - } - if (changesMask[74]) - { - data << float(DodgePercentageFromAttribute); - } - if (changesMask[75]) - { - data << float(ParryPercentage); - } - if (changesMask[76]) - { - data << float(ParryPercentageFromAttribute); - } - if (changesMask[77]) - { - data << float(CritPercentage); - } - if (changesMask[78]) - { - data << float(RangedCritPercentage); - } - if (changesMask[79]) - { - data << float(OffhandCritPercentage); - } - if (changesMask[80]) - { - data << float(SpellCritPercentage); - } - if (changesMask[81]) - { - data << int32(ShieldBlock); - } - if (changesMask[82]) - { - data << float(ShieldBlockCritPercentage); - } - if (changesMask[83]) - { - data << float(Mastery); - } - if (changesMask[84]) - { - data << float(Speed); - } - if (changesMask[85]) - { - data << float(Avoidance); - } - if (changesMask[86]) - { - data << float(Sturdiness); - } - if (changesMask[87]) - { - data << int32(Versatility); - } - if (changesMask[88]) - { - data << float(VersatilityBonus); - } - if (changesMask[89]) - { - data << float(PvpPowerDamage); - } - if (changesMask[90]) - { - data << float(PvpPowerHealing); - } - if (changesMask[91]) - { - BitVectors->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[92]) - { - data << int32(ModHealingDonePos); - } - if (changesMask[93]) - { - data << float(ModHealingPercent); - } - if (changesMask[94]) - { - data << float(ModPeriodicHealingDonePercent); - } - if (changesMask[95]) - { - data << float(ModSpellPowerPercent); - } - if (changesMask[96]) - { - data << float(ModResiliencePercent); - } - if (changesMask[97]) - { - data << float(OverrideSpellPowerByAPPercent); - } - if (changesMask[98]) - { - data << float(OverrideAPBySpellPowerPercent); - } - if (changesMask[99]) - { - data << int32(ModTargetResistance); - } - if (changesMask[100]) - { - data << int32(ModTargetPhysicalResistance); - } - if (changesMask[101]) - { - data << uint32(LocalFlags); - } - } - if (changesMask[102]) - { - if (changesMask[103]) - { - data << uint8(GrantableLevels); - } - if (changesMask[104]) - { - data << uint8(MultiActionBars); - } - if (changesMask[105]) - { - data << uint8(LifetimeMaxRank); - } - if (changesMask[106]) - { - data << uint8(NumRespecs); - } - if (changesMask[107]) - { - data << uint32(PvpMedals); - } - if (changesMask[108]) - { - data << uint16(TodayHonorableKills); - } - if (changesMask[109]) - { - data << uint16(YesterdayHonorableKills); - } - if (changesMask[110]) - { - data << uint32(LifetimeHonorableKills); - } - if (changesMask[111]) - { - data << int32(WatchedFactionIndex); - } - if (changesMask[112]) - { - data << int32(MaxLevel); - } - if (changesMask[113]) - { - data << int32(ScalingPlayerLevelDelta); - } - if (changesMask[114]) - { - data << int32(MaxCreatureScalingLevel); - } - if (changesMask[115]) - { - data << uint8(TransmogCostMinScalingLevel); - } - if (changesMask[116]) - { - data << int32(PetSpellPower); - } - if (changesMask[117]) - { - data << float(UiHitModifier); - } - if (changesMask[118]) - { - data << float(UiSpellHitModifier); - } - if (changesMask[119]) - { - data << int32(HomeRealmTimeOffset); - } - if (changesMask[120]) - { - data << float(ModPetHaste); - } - if (changesMask[121]) - { - data << int8(JailersTowerLevelMax); - } - if (changesMask[122]) - { - data << int8(JailersTowerLevel); - } - if (changesMask[123]) - { - data << uint8(LocalRegenFlags); - } - if (changesMask[124]) - { - data << uint8(AuraVision); - } - if (changesMask[125]) - { - data << uint8(NumBackpackSlots); - } - if (changesMask[126]) - { - data << int32(OverrideSpellsID); - } - if (changesMask[127]) - { - data << uint16(LootSpecID); - } - if (changesMask[128]) - { - data << uint32(OverrideZonePVPType); - } - if (changesMask[129]) - { - data << int32(Honor); - } - if (changesMask[130]) - { - data << int32(HonorNextLevel); - } - if (changesMask[131]) - { - data << int32(PerksProgramCurrency); - } - if (changesMask[132]) - { - data << uint8(NumBankSlots); - } - if (changesMask[133]) - { - data << uint8(NumCharacterBankTabs); - } - } - if (changesMask[134]) - { - if (changesMask[135]) - { - data << uint8(NumAccountBankTabs); - } - if (changesMask[140]) - { - data << int32(UiChromieTimeExpansionID); - } - if (changesMask[141]) - { - data << int32(TimerunningSeasonID); - } - if (changesMask[142]) - { - data << int32(TransportServerTime); - } - if (changesMask[143]) - { - data << uint32(WeeklyRewardsPeriodSinceOrigin); - } - if (changesMask[144]) - { - data << int16(DEBUGSoulbindConduitRank); - } - if (changesMask[147]) - { - data << uint32(ActiveCombatTraitConfigID); - } - if (changesMask[148]) - { - data << int32(ItemUpgradeHighOnehandWeaponItemID); - } - if (changesMask[149]) - { - data << int32(ItemUpgradeHighFingerItemID); - } - if (changesMask[150]) - { - data << float(ItemUpgradeHighFingerWatermark); - } - if (changesMask[151]) - { - data << int32(ItemUpgradeHighTrinketItemID); - } - if (changesMask[152]) - { - data << float(ItemUpgradeHighTrinketWatermark); - } - if (changesMask[153]) - { - data << uint64(LootHistoryInstanceID); - } - if (changesMask[155]) - { - data << uint8(RequiredMountCapabilityFlags); - } - data.WriteBits(QuestSession.has_value(), 1); - data.WriteBits(PetStable.has_value(), 1); - data.WriteBits(WalkInData.has_value(), 1); - data.WriteBits(DelveData.has_value(), 1); - data.WriteBits(ChallengeModeData.has_value(), 1); - } - data.FlushBits(); - if (changesMask[134]) - { - if (changesMask[136]) - { - ResearchHistory->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[138]) - { - if (QuestSession.has_value()) - { - QuestSession->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[137]) - { - data << *FrozenPerksVendorItem; - } - if (changesMask[139]) - { - LevelLinkInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[145]) - { - data << *DungeonScore; - } - if (changesMask[146]) - { - WriteMapFieldUpdate(TraitConfigs, ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[159]) - { - WriteMapFieldUpdate(TransmogOutfits, ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[160]) - { - ViewedOutfit->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[161]) - { - TransmogMetadata->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[154]) - { - if (PetStable.has_value()) - { - PetStable->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[156]) - { - if (WalkInData.has_value()) - { - WalkInData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[157]) - { - if (DelveData.has_value()) - { - DelveData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[158]) - { - if (ChallengeModeData.has_value()) - { - ChallengeModeData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[162]) - { - for (uint32 i = 0; i < 105; ++i) - { - if (changesMask[163 + i]) - { - data << InvSlots[i]; - } - } - } - if (changesMask[268]) - { - for (uint32 i = 0; i < 2; ++i) - { - if (changesMask[269 + i]) - { - RestInfo[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[271]) - { - for (uint32 i = 0; i < 7; ++i) - { - if (changesMask[272 + i]) - { - data << int32(ModDamageDonePos[i]); - } - if (changesMask[279 + i]) - { - data << int32(ModDamageDoneNeg[i]); - } - if (changesMask[286 + i]) - { - data << float(ModDamageDonePercent[i]); - } - if (changesMask[293 + i]) - { - data << float(ModHealingDonePercent[i]); - } - } - } - if (changesMask[300]) - { - for (uint32 i = 0; i < 3; ++i) - { - if (changesMask[301 + i]) - { - data << float(WeaponDmgMultipliers[i]); - } - if (changesMask[304 + i]) - { - data << float(WeaponAtkSpeedMultipliers[i]); - } - } - } - if (changesMask[307]) - { - for (uint32 i = 0; i < 12; ++i) - { - if (changesMask[308 + i]) - { - data << uint32(BuybackPrice[i]); - } - if (changesMask[320 + i]) - { - data << int64(BuybackTimestamp[i]); - } - } - } - if (changesMask[332]) - { - for (uint32 i = 0; i < 32; ++i) - { - if (changesMask[333 + i]) - { - data << int32(CombatRatings[i]); - } - } - } - if (changesMask[365]) - { - for (uint32 i = 0; i < 4; ++i) - { - if (changesMask[366 + i]) - { - data << uint32(NoReagentCostMask[i]); - } - } - } - if (changesMask[370]) - { - for (uint32 i = 0; i < 2; ++i) - { - if (changesMask[371 + i]) - { - data << int32(ProfessionSkillLine[i]); - } - } - } - if (changesMask[373]) - { - for (uint32 i = 0; i < 5; ++i) - { - if (changesMask[374 + i]) - { - data << uint32(BagSlotFlags[i]); - } - } - } - if (changesMask[379]) - { - for (uint32 i = 0; i < 17; ++i) - { - if (changesMask[380 + i]) - { - data << float(ItemUpgradeHighWatermark[i]); - } - } - } - data.FlushBits(); -} - -void ActivePlayerData::ClearChangesMask() -{ - Base::ClearChangesMask(BackpackAutoSortDisabled); - Base::ClearChangesMask(BackpackSellJunkDisabled); - Base::ClearChangesMask(BankAutoSortDisabled); - Base::ClearChangesMask(SortBagsRightToLeft); - Base::ClearChangesMask(InsertItemsLeftToRight); - Base::ClearChangesMask(HasPerksProgramPendingReward); - Base::ClearChangesMask(ResearchSites); - Base::ClearChangesMask(ResearchSiteProgress); - Base::ClearChangesMask(Research); - Base::ClearChangesMask(KnownTitles); - Base::ClearChangesMask(CharacterDataElements); - Base::ClearChangesMask(AccountDataElements); - Base::ClearChangesMask(DailyQuestsCompleted); - Base::ClearChangesMask(Field_1328); - Base::ClearChangesMask(AvailableQuestLineXQuestIDs); - Base::ClearChangesMask(Heirlooms); - Base::ClearChangesMask(HeirloomFlags); - Base::ClearChangesMask(Toys); - Base::ClearChangesMask(ToyFlags); - Base::ClearChangesMask(Transmog); - Base::ClearChangesMask(ConditionalTransmog); - Base::ClearChangesMask(SelfResSpells); - Base::ClearChangesMask(RuneforgePowers); - Base::ClearChangesMask(TransmogIllusions); - Base::ClearChangesMask(WarbandScenes); - Base::ClearChangesMask(HouseRooms); - Base::ClearChangesMask(HouseExteriorComponents); - Base::ClearChangesMask(HouseThemes); - Base::ClearChangesMask(HouseRoomComponentTextures); - Base::ClearChangesMask(HouseTypes); - Base::ClearChangesMask(Field_1980); - Base::ClearChangesMask(SpellPctModByLabel); - Base::ClearChangesMask(SpellFlatModByLabel); - Base::ClearChangesMask(SpellPctModPVPByLabel); - Base::ClearChangesMask(SpellFlatModPVPByLabel); - Base::ClearChangesMask(MawPowers); - Base::ClearChangesMask(MultiFloorExploration); - Base::ClearChangesMask(RecipeProgression); - Base::ClearChangesMask(ReplayedQuests); - Base::ClearChangesMask(TaskQuests); - Base::ClearChangesMask(DisabledSpells); - Base::ClearChangesMask(PersonalCraftingOrderCounts); - Base::ClearChangesMask(NpcCraftingOrders); - Base::ClearChangesMask(CategoryCooldownMods); - Base::ClearChangesMask(WeeklySpellUses); - Base::ClearChangesMask(TrackedCollectableSources); - Base::ClearChangesMask(PvpInfo); - Base::ClearChangesMask(CharacterRestrictions); - Base::ClearChangesMask(CraftingOrders); - Base::ClearChangesMask(CharacterBankTabSettings); - Base::ClearChangesMask(AccountBankTabSettings); - Base::ClearChangesMask(FarsightObject); - Base::ClearChangesMask(SummonedBattlePetGUID); - Base::ClearChangesMask(Coinage); - Base::ClearChangesMask(AccountBankCoinage); - Base::ClearChangesMask(XP); - Base::ClearChangesMask(NextLevelXP); - Base::ClearChangesMask(TrialXP); - Base::ClearChangesMask(Skill); - Base::ClearChangesMask(CharacterPoints); - Base::ClearChangesMask(MaxTalentTiers); - Base::ClearChangesMask(TrackCreatureMask); - Base::ClearChangesMask(MainhandExpertise); - Base::ClearChangesMask(OffhandExpertise); - Base::ClearChangesMask(RangedExpertise); - Base::ClearChangesMask(CombatRatingExpertise); - Base::ClearChangesMask(BlockPercentage); - Base::ClearChangesMask(DodgePercentage); - Base::ClearChangesMask(DodgePercentageFromAttribute); - Base::ClearChangesMask(ParryPercentage); - Base::ClearChangesMask(ParryPercentageFromAttribute); - Base::ClearChangesMask(CritPercentage); - Base::ClearChangesMask(RangedCritPercentage); - Base::ClearChangesMask(OffhandCritPercentage); - Base::ClearChangesMask(SpellCritPercentage); - Base::ClearChangesMask(ShieldBlock); - Base::ClearChangesMask(ShieldBlockCritPercentage); - Base::ClearChangesMask(Mastery); - Base::ClearChangesMask(Speed); - Base::ClearChangesMask(Avoidance); - Base::ClearChangesMask(Sturdiness); - Base::ClearChangesMask(Versatility); - Base::ClearChangesMask(VersatilityBonus); - Base::ClearChangesMask(PvpPowerDamage); - Base::ClearChangesMask(PvpPowerHealing); - Base::ClearChangesMask(BitVectors); - Base::ClearChangesMask(ModHealingDonePos); - Base::ClearChangesMask(ModHealingPercent); - Base::ClearChangesMask(ModPeriodicHealingDonePercent); - Base::ClearChangesMask(ModSpellPowerPercent); - Base::ClearChangesMask(ModResiliencePercent); - Base::ClearChangesMask(OverrideSpellPowerByAPPercent); - Base::ClearChangesMask(OverrideAPBySpellPowerPercent); - Base::ClearChangesMask(ModTargetResistance); - Base::ClearChangesMask(ModTargetPhysicalResistance); - Base::ClearChangesMask(LocalFlags); - Base::ClearChangesMask(GrantableLevels); - Base::ClearChangesMask(MultiActionBars); - Base::ClearChangesMask(LifetimeMaxRank); - Base::ClearChangesMask(NumRespecs); - Base::ClearChangesMask(PvpMedals); - Base::ClearChangesMask(TodayHonorableKills); - Base::ClearChangesMask(YesterdayHonorableKills); - Base::ClearChangesMask(LifetimeHonorableKills); - Base::ClearChangesMask(WatchedFactionIndex); - Base::ClearChangesMask(MaxLevel); - Base::ClearChangesMask(ScalingPlayerLevelDelta); - Base::ClearChangesMask(MaxCreatureScalingLevel); - Base::ClearChangesMask(TransmogCostMinScalingLevel); - Base::ClearChangesMask(PetSpellPower); - Base::ClearChangesMask(UiHitModifier); - Base::ClearChangesMask(UiSpellHitModifier); - Base::ClearChangesMask(HomeRealmTimeOffset); - Base::ClearChangesMask(ModPetHaste); - Base::ClearChangesMask(JailersTowerLevelMax); - Base::ClearChangesMask(JailersTowerLevel); - Base::ClearChangesMask(LocalRegenFlags); - Base::ClearChangesMask(AuraVision); - Base::ClearChangesMask(NumBackpackSlots); - Base::ClearChangesMask(OverrideSpellsID); - Base::ClearChangesMask(LootSpecID); - Base::ClearChangesMask(OverrideZonePVPType); - Base::ClearChangesMask(Honor); - Base::ClearChangesMask(HonorNextLevel); - Base::ClearChangesMask(PerksProgramCurrency); - Base::ClearChangesMask(NumBankSlots); - Base::ClearChangesMask(NumCharacterBankTabs); - Base::ClearChangesMask(NumAccountBankTabs); - Base::ClearChangesMask(ResearchHistory); - Base::ClearChangesMask(FrozenPerksVendorItem); - Base::ClearChangesMask(LevelLinkInfo); - Base::ClearChangesMask(QuestSession); - Base::ClearChangesMask(UiChromieTimeExpansionID); - Base::ClearChangesMask(TimerunningSeasonID); - Base::ClearChangesMask(TransportServerTime); - Base::ClearChangesMask(WeeklyRewardsPeriodSinceOrigin); - Base::ClearChangesMask(DEBUGSoulbindConduitRank); - Base::ClearChangesMask(DungeonScore); - Base::ClearChangesMask(TraitConfigs); - Base::ClearChangesMask(ActiveCombatTraitConfigID); - Base::ClearChangesMask(ItemUpgradeHighOnehandWeaponItemID); - Base::ClearChangesMask(ItemUpgradeHighFingerItemID); - Base::ClearChangesMask(ItemUpgradeHighFingerWatermark); - Base::ClearChangesMask(ItemUpgradeHighTrinketItemID); - Base::ClearChangesMask(ItemUpgradeHighTrinketWatermark); - Base::ClearChangesMask(LootHistoryInstanceID); - Base::ClearChangesMask(PetStable); - Base::ClearChangesMask(RequiredMountCapabilityFlags); - Base::ClearChangesMask(WalkInData); - Base::ClearChangesMask(DelveData); - Base::ClearChangesMask(ChallengeModeData); - Base::ClearChangesMask(TransmogOutfits); - Base::ClearChangesMask(ViewedOutfit); - Base::ClearChangesMask(TransmogMetadata); - Base::ClearChangesMask(InvSlots); - Base::ClearChangesMask(RestInfo); - Base::ClearChangesMask(ModDamageDonePos); - Base::ClearChangesMask(ModDamageDoneNeg); - Base::ClearChangesMask(ModDamageDonePercent); - Base::ClearChangesMask(ModHealingDonePercent); - Base::ClearChangesMask(WeaponDmgMultipliers); - Base::ClearChangesMask(WeaponAtkSpeedMultipliers); - Base::ClearChangesMask(BuybackPrice); - Base::ClearChangesMask(BuybackTimestamp); - Base::ClearChangesMask(CombatRatings); - Base::ClearChangesMask(NoReagentCostMask); - Base::ClearChangesMask(ProfessionSkillLine); - Base::ClearChangesMask(BagSlotFlags); - Base::ClearChangesMask(ItemUpgradeHighWatermark); - _changesMask.ResetAll(); -} - -void GameObjectAssistActionData::WriteCreate(ByteBuffer& data, Player const* receiver, GameObject const* owner) const -{ - data.WriteBits(PlayerName.size(), 6); - data.WriteBits(MonsterName.size() + 1, 11); - data << uint32(VirtualRealmAddress); - data << uint8(Sex); - data << int64(Time); - data << int32(DelveTier); - data << WorldPackets::SizedString::Data(PlayerName); - data << WorldPackets::SizedCString::Data(MonsterName); -} - -void GameObjectAssistActionData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, GameObject const* owner) const -{ - data.WriteBits(PlayerName.size(), 6); - data.WriteBits(MonsterName.size() + 1, 11); - data << uint32(VirtualRealmAddress); - data << uint8(Sex); - data << int64(Time); - data << int32(DelveTier); - data << WorldPackets::SizedString::Data(PlayerName); - data << WorldPackets::SizedCString::Data(MonsterName); -} - -bool GameObjectAssistActionData::operator==(GameObjectAssistActionData const& right) const -{ - return PlayerName == right.PlayerName - && MonsterName == right.MonsterName - && VirtualRealmAddress == right.VirtualRealmAddress - && Sex == right.Sex - && Time == right.Time - && DelveTier == right.DelveTier; -} - -void GameObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const -{ - ViewerDependentValue::value_type stateWorldEffectIDs = {}; - - data << int32(DisplayID); - data << uint32(SpellVisualID); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); - data << uint32(stateWorldEffectIDs->size()); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) - { - data << uint32((*stateWorldEffectIDs)[i]); - } - data << *CreatedBy; - data << *GuildGUID; - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << float(ParentRotation->x); - data << float(ParentRotation->y); - data << float(ParentRotation->z); - data << float(ParentRotation->w); - data << int32(FactionTemplate); - data << int8(ViewerDependentValue::GetValue(this, receiver, owner)); - data << int8(TypeID); - data << uint8(PercentHealth); - data << uint32(ArtKit); - data << uint32(EnableDoodadSets.size()); - data << uint32(CustomParam); - data << int32(Level); - data << uint32(AnimGroupInstance); - data << uint32(UiWidgetItemID); - data << uint32(UiWidgetItemQuality); - data << uint32(UiWidgetItemCount); - data << uint32(WorldEffects.size()); - for (uint32 i = 0; i < EnableDoodadSets.size(); ++i) - { - data << int32(EnableDoodadSets[i]); - } - for (uint32 i = 0; i < WorldEffects.size(); ++i) - { - data << int32(WorldEffects[i]); - } - data.WriteBits(AssistActionData.has_value(), 1); - data.FlushBits(); - if (AssistActionData.has_value()) - { - AssistActionData->WriteCreate(data, receiver, owner); - } -} - -void GameObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void GameObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, GameObject const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 26); - - ViewerDependentValue::value_type stateWorldEffectIDs = {}; - - if (changesMask[0]) - { - if (changesMask[1]) - { - stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); - data.WriteBits(stateWorldEffectIDs->size(), 32); - for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) - { - data << uint32((*stateWorldEffectIDs)[i]); - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - if (!ignoreNestedChangesMask) - EnableDoodadSets.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(EnableDoodadSets.size(), data); - } - if (changesMask[3]) - { - if (!ignoreNestedChangesMask) - WorldEffects.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(WorldEffects.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - for (uint32 i = 0; i < EnableDoodadSets.size(); ++i) - { - if (EnableDoodadSets.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(EnableDoodadSets[i]); - } - } - } - if (changesMask[3]) - { - for (uint32 i = 0; i < WorldEffects.size(); ++i) - { - if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask) - { - data << int32(WorldEffects[i]); - } - } - } - if (changesMask[4]) - { - data << int32(DisplayID); - } - if (changesMask[5]) - { - data << uint32(SpellVisualID); - } - if (changesMask[6]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[7]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[8]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[9]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[10]) - { - data << *CreatedBy; - } - if (changesMask[11]) - { - data << *GuildGUID; - } - if (changesMask[12]) - { - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[13]) - { - data << float(ParentRotation->x); - data << float(ParentRotation->y); - data << float(ParentRotation->z); - data << float(ParentRotation->w); - } - if (changesMask[14]) - { - data << int32(FactionTemplate); - } - if (changesMask[15]) - { - data << int8(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[16]) - { - data << int8(TypeID); - } - if (changesMask[17]) - { - data << uint8(PercentHealth); - } - if (changesMask[18]) - { - data << uint32(ArtKit); - } - if (changesMask[19]) - { - data << uint32(CustomParam); - } - if (changesMask[20]) - { - data << int32(Level); - } - if (changesMask[21]) - { - data << uint32(AnimGroupInstance); - } - if (changesMask[22]) - { - data << uint32(UiWidgetItemID); - } - if (changesMask[23]) - { - data << uint32(UiWidgetItemQuality); - } - if (changesMask[24]) - { - data << uint32(UiWidgetItemCount); - } - data.WriteBits(AssistActionData.has_value(), 1); data.FlushBits(); - if (changesMask[25]) + if (changesMask[0]) { - if (AssistActionData.has_value()) - { - AssistActionData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } + data << uint64(OrderItemID); } - } -} - -void GameObjectData::ClearChangesMask() -{ - Base::ClearChangesMask(StateWorldEffectIDs); - Base::ClearChangesMask(EnableDoodadSets); - Base::ClearChangesMask(WorldEffects); - Base::ClearChangesMask(DisplayID); - Base::ClearChangesMask(SpellVisualID); - Base::ClearChangesMask(StateSpellVisualID); - Base::ClearChangesMask(SpawnTrackingStateAnimID); - Base::ClearChangesMask(SpawnTrackingStateAnimKitID); - Base::ClearChangesMask(StateWorldEffectsQuestObjectiveID); - Base::ClearChangesMask(CreatedBy); - Base::ClearChangesMask(GuildGUID); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(ParentRotation); - Base::ClearChangesMask(FactionTemplate); - Base::ClearChangesMask(State); - Base::ClearChangesMask(TypeID); - Base::ClearChangesMask(PercentHealth); - Base::ClearChangesMask(ArtKit); - Base::ClearChangesMask(CustomParam); - Base::ClearChangesMask(Level); - Base::ClearChangesMask(AnimGroupInstance); - Base::ClearChangesMask(UiWidgetItemID); - Base::ClearChangesMask(UiWidgetItemQuality); - Base::ClearChangesMask(UiWidgetItemCount); - Base::ClearChangesMask(AssistActionData); - _changesMask.ResetAll(); -} - -void DynamicObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, DynamicObject const* owner) const -{ - data << *Caster; - data << uint8(Type); - SpellVisual->WriteCreate(data, receiver, owner); - data << int32(SpellID); - data << float(Radius); - data << uint32(CastTime); -} - -void DynamicObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, DynamicObject const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void DynamicObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, DynamicObject const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 7); - - data.FlushBits(); - if (changesMask[0]) - { if (changesMask[1]) { - data << *Caster; + data << *ItemGUID; } if (changesMask[2]) - { - data << uint8(Type); - } - if (changesMask[3]) - { - SpellVisual->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[4]) - { - data << int32(SpellID); - } - if (changesMask[5]) - { - data << float(Radius); - } - if (changesMask[6]) - { - data << uint32(CastTime); - } - } -} - -void DynamicObjectData::ClearChangesMask() -{ - Base::ClearChangesMask(Caster); - Base::ClearChangesMask(Type); - Base::ClearChangesMask(SpellVisual); - Base::ClearChangesMask(SpellID); - Base::ClearChangesMask(Radius); - Base::ClearChangesMask(CastTime); - _changesMask.ResetAll(); -} - -void CorpseData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Corpse const* owner) const -{ - data << uint32(DynamicFlags); - data << *Owner; - data << *PartyGUID; - data << *GuildGUID; - data << uint32(DisplayID); - for (uint32 i = 0; i < 19; ++i) - { - data << uint32(Items[i]); - } - data << uint8(RaceID); - data << uint8(Sex); - data << uint8(Class); - data << uint32(Customizations.size()); - data << uint32(Flags); - data << int32(FactionTemplate); - data << uint32(StateSpellVisualKitID); - for (uint32 i = 0; i < Customizations.size(); ++i) - { - Customizations[i].WriteCreate(data, receiver, owner); - } -} - -void CorpseData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Corpse const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void CorpseData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Corpse const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlocksMask(0), 2); - for (uint32 i = 0; i < 2; ++i) - if (changesMask.GetBlock(i)) - data.WriteBits(changesMask.GetBlock(i), 32); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreNestedChangesMask) - Customizations.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Customizations.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < Customizations.size(); ++i) - { - if (Customizations.HasChanged(i) || ignoreNestedChangesMask) - { - Customizations[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - data << uint32(DynamicFlags); - } - if (changesMask[3]) - { - data << *Owner; - } - if (changesMask[4]) - { - data << *PartyGUID; - } - if (changesMask[5]) - { - data << *GuildGUID; - } - if (changesMask[6]) - { - data << uint32(DisplayID); - } - if (changesMask[7]) - { - data << uint8(RaceID); - } - if (changesMask[8]) - { - data << uint8(Sex); - } - if (changesMask[9]) - { - data << uint8(Class); - } - if (changesMask[10]) - { - data << uint32(Flags); - } - if (changesMask[11]) - { - data << int32(FactionTemplate); - } - if (changesMask[12]) - { - data << uint32(StateSpellVisualKitID); - } - } - if (changesMask[13]) - { - for (uint32 i = 0; i < 19; ++i) - { - if (changesMask[14 + i]) - { - data << uint32(Items[i]); - } - } - } -} - -void CorpseData::ClearChangesMask() -{ - Base::ClearChangesMask(Customizations); - Base::ClearChangesMask(DynamicFlags); - Base::ClearChangesMask(Owner); - Base::ClearChangesMask(PartyGUID); - Base::ClearChangesMask(GuildGUID); - Base::ClearChangesMask(DisplayID); - Base::ClearChangesMask(RaceID); - Base::ClearChangesMask(Sex); - Base::ClearChangesMask(Class); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(FactionTemplate); - Base::ClearChangesMask(StateSpellVisualKitID); - Base::ClearChangesMask(Items); - _changesMask.ResetAll(); -} - -void ScaleCurve::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << uint32(StartTimeOffset); - for (uint32 i = 0; i < 2; ++i) - { - data << Points[i]; - } - data << uint32(ParameterCurve); - data.WriteBit(OverrideActive); - data.FlushBits(); -} - -void ScaleCurve::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 7); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(OverrideActive); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - data << uint32(StartTimeOffset); - } - if (changesMask[3]) - { - data << uint32(ParameterCurve); - } - } - if (changesMask[4]) - { - for (uint32 i = 0; i < 2; ++i) - { - if (changesMask[5 + i]) - { - data << Points[i]; - } - } - } - data.FlushBits(); -} - -void ScaleCurve::ClearChangesMask() -{ - Base::ClearChangesMask(OverrideActive); - Base::ClearChangesMask(StartTimeOffset); - Base::ClearChangesMask(ParameterCurve); - Base::ClearChangesMask(Points); - _changesMask.ResetAll(); -} - -void VisualAnim::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data.WriteBits(AnimationDataID.has_value(), 1); - data.WriteBit(IsDecay); - data.FlushBits(); - data << uint32(AnimKitID); - data << uint32(AnimProgress); - if (AnimationDataID.has_value()) - { - data << int16(AnimationDataID); - } - data.FlushBits(); -} - -void VisualAnim::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 5); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(IsDecay); - } - data.WriteBits(AnimationDataID.has_value(), 1); - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - data << uint32(AnimKitID); - } - if (changesMask[4]) - { - data << uint32(AnimProgress); - } - if (changesMask[2]) - { - if (AnimationDataID.has_value()) - { - data << int16(AnimationDataID); - } - } - } - data.FlushBits(); -} - -void VisualAnim::ClearChangesMask() -{ - Base::ClearChangesMask(IsDecay); - Base::ClearChangesMask(AnimationDataID); - Base::ClearChangesMask(AnimKitID); - Base::ClearChangesMask(AnimProgress); - _changesMask.ResetAll(); -} - -void ForceSetAreaTriggerPositionAndRotation::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << TriggerGUID; - data << Pos; - data << float(Rotation.x); - data << float(Rotation.y); - data << float(Rotation.z); - data << float(Rotation.w); -} - -void ForceSetAreaTriggerPositionAndRotation::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << TriggerGUID; - data << Pos; - data << float(Rotation.x); - data << float(Rotation.y); - data << float(Rotation.z); - data << float(Rotation.w); -} - -bool ForceSetAreaTriggerPositionAndRotation::operator==(ForceSetAreaTriggerPositionAndRotation const& right) const -{ - return TriggerGUID == right.TriggerGUID - && Pos == right.Pos - && Rotation == right.Rotation; -} - -void AreaTriggerActionSetPeriodModifier::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << int32(Field_0); - data << float(Field_4); -} - -void AreaTriggerActionSetPeriodModifier::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(Field_0); - } - if (changesMask[2]) - { - data << float(Field_4); - } - } -} - -void AreaTriggerActionSetPeriodModifier::ClearChangesMask() -{ - Base::ClearChangesMask(Field_0); - Base::ClearChangesMask(Field_4); - _changesMask.ResetAll(); -} - -void AreaTriggerSplineCalculator::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data.WriteBits(Points.size(), 16); - data.WriteBit(Catmullrom); - for (uint32 i = 0; i < Points.size(); ++i) - { - data << Points[i]; - } - data.FlushBits(); -} - -void AreaTriggerSplineCalculator::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(Catmullrom); - } - if (changesMask[2]) - { - if (!ignoreChangesMask) - Points.WriteUpdateMask(data, 16); - else - WriteCompleteDynamicFieldUpdateMask(Points.size(), data, 16); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - for (uint32 i = 0; i < Points.size(); ++i) - { - if (Points.HasChanged(i) || ignoreChangesMask) - { - data << Points[i]; - } - } - } - } - data.FlushBits(); -} - -void AreaTriggerSplineCalculator::ClearChangesMask() -{ - Base::ClearChangesMask(Catmullrom); - Base::ClearChangesMask(Points); - _changesMask.ResetAll(); -} - -void AreaTriggerOrbit::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << *Center; - data << float(Radius); - data << float(InitialAngle); - data << float(BlendFromRadius); - data << int32(ExtraTimeForBlending); - data.WriteBit(CounterClockwise); - data.FlushBits(); -} - -void AreaTriggerOrbit::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 7); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(CounterClockwise); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) - { - data << *Center; - } - if (changesMask[3]) - { - data << float(Radius); - } - if (changesMask[4]) - { - data << float(InitialAngle); - } - if (changesMask[5]) - { - data << float(BlendFromRadius); - } - if (changesMask[6]) - { - data << int32(ExtraTimeForBlending); - } - } - data.FlushBits(); -} - -void AreaTriggerOrbit::ClearChangesMask() -{ - Base::ClearChangesMask(CounterClockwise); - Base::ClearChangesMask(Center); - Base::ClearChangesMask(Radius); - Base::ClearChangesMask(InitialAngle); - Base::ClearChangesMask(BlendFromRadius); - Base::ClearChangesMask(ExtraTimeForBlending); - _changesMask.ResetAll(); -} - -void AreaTriggerMovementScript::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << int32(SpellScriptID); - data << *Center; - data << uint32(CreationTime); -} - -void AreaTriggerMovementScript::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(SpellScriptID); - } - if (changesMask[2]) - { - data << *Center; - } - if (changesMask[3]) - { - data << uint32(CreationTime); - } - } -} - -void AreaTriggerMovementScript::ClearChangesMask() -{ - Base::ClearChangesMask(SpellScriptID); - Base::ClearChangesMask(Center); - Base::ClearChangesMask(CreationTime); - _changesMask.ResetAll(); -} - -void AreaTriggerSphere::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << float(Radius); - data << float(RadiusTarget); -} - -void AreaTriggerSphere::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << float(Radius); - } - if (changesMask[2]) - { - data << float(RadiusTarget); - } - } -} - -void AreaTriggerSphere::ClearChangesMask() -{ - Base::ClearChangesMask(Radius); - Base::ClearChangesMask(RadiusTarget); - _changesMask.ResetAll(); -} - -void AreaTriggerBox::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << *Extents; - data << *ExtentsTarget; -} - -void AreaTriggerBox::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *Extents; - } - if (changesMask[2]) - { - data << *ExtentsTarget; - } - } -} - -void AreaTriggerBox::ClearChangesMask() -{ - Base::ClearChangesMask(Extents); - Base::ClearChangesMask(ExtentsTarget); - _changesMask.ResetAll(); -} - -void AreaTriggerPolygon::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << uint32(Vertices.size()); - data << uint32(VerticesTarget.size()); - data << float(Height); - data << float(HeightTarget); - for (uint32 i = 0; i < Vertices.size(); ++i) - { - data << Vertices[i]; - } - for (uint32 i = 0; i < VerticesTarget.size(); ++i) - { - data << VerticesTarget[i]; - } -} - -void AreaTriggerPolygon::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 5); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreChangesMask) - Vertices.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Vertices.size(), data); - } - if (changesMask[2]) - { - if (!ignoreChangesMask) - VerticesTarget.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(VerticesTarget.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < Vertices.size(); ++i) - { - if (Vertices.HasChanged(i) || ignoreChangesMask) - { - data << Vertices[i]; - } - } - } - if (changesMask[2]) - { - for (uint32 i = 0; i < VerticesTarget.size(); ++i) - { - if (VerticesTarget.HasChanged(i) || ignoreChangesMask) - { - data << VerticesTarget[i]; - } - } - } - if (changesMask[3]) - { - data << float(Height); - } - if (changesMask[4]) - { - data << float(HeightTarget); - } - } -} - -void AreaTriggerPolygon::ClearChangesMask() -{ - Base::ClearChangesMask(Vertices); - Base::ClearChangesMask(VerticesTarget); - Base::ClearChangesMask(Height); - Base::ClearChangesMask(HeightTarget); - _changesMask.ResetAll(); -} - -void AreaTriggerCylinder::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << float(Radius); - data << float(RadiusTarget); - data << float(Height); - data << float(HeightTarget); - data << float(LocationZOffset); - data << float(LocationZOffsetTarget); -} - -void AreaTriggerCylinder::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 7); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << float(Radius); - } - if (changesMask[2]) - { - data << float(RadiusTarget); - } - if (changesMask[3]) - { - data << float(Height); - } - if (changesMask[4]) - { - data << float(HeightTarget); - } - if (changesMask[5]) - { - data << float(LocationZOffset); - } - if (changesMask[6]) - { - data << float(LocationZOffsetTarget); - } - } -} - -void AreaTriggerCylinder::ClearChangesMask() -{ - Base::ClearChangesMask(Radius); - Base::ClearChangesMask(RadiusTarget); - Base::ClearChangesMask(Height); - Base::ClearChangesMask(HeightTarget); - Base::ClearChangesMask(LocationZOffset); - Base::ClearChangesMask(LocationZOffsetTarget); - _changesMask.ResetAll(); -} - -void AreaTriggerDisk::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << float(InnerRadius); - data << float(InnerRadiusTarget); - data << float(OuterRadius); - data << float(OuterRadiusTarget); - data << float(Height); - data << float(HeightTarget); - data << float(LocationZOffset); - data << float(LocationZOffsetTarget); -} - -void AreaTriggerDisk::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 9); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << float(InnerRadius); - } - if (changesMask[2]) - { - data << float(InnerRadiusTarget); - } - if (changesMask[3]) - { - data << float(OuterRadius); - } - if (changesMask[4]) - { - data << float(OuterRadiusTarget); - } - if (changesMask[5]) - { - data << float(Height); - } - if (changesMask[6]) - { - data << float(HeightTarget); - } - if (changesMask[7]) - { - data << float(LocationZOffset); - } - if (changesMask[8]) - { - data << float(LocationZOffsetTarget); - } - } -} - -void AreaTriggerDisk::ClearChangesMask() -{ - Base::ClearChangesMask(InnerRadius); - Base::ClearChangesMask(InnerRadiusTarget); - Base::ClearChangesMask(OuterRadius); - Base::ClearChangesMask(OuterRadiusTarget); - Base::ClearChangesMask(Height); - Base::ClearChangesMask(HeightTarget); - Base::ClearChangesMask(LocationZOffset); - Base::ClearChangesMask(LocationZOffsetTarget); - _changesMask.ResetAll(); -} - -void AreaTriggerBoundedPlane::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << *Extents; - data << *ExtentsTarget; -} - -void AreaTriggerBoundedPlane::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *Extents; - } - if (changesMask[2]) - { - data << *ExtentsTarget; - } - } -} - -void AreaTriggerBoundedPlane::ClearChangesMask() -{ - Base::ClearChangesMask(Extents); - Base::ClearChangesMask(ExtentsTarget); - _changesMask.ResetAll(); -} - -void AreaTriggerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - OverrideScaleCurve->WriteCreate(data, receiver, owner); - data << *Caster; - data << uint32(Duration); - data << uint32(TimeToTarget); - data << uint32(TimeToTargetScale); - data << uint32(TimeToTargetExtraScale); - data << uint32(TimeToTargetPos); - data << int32(SpellID); - data << int32(SpellForVisuals); - SpellVisual->WriteCreate(data, receiver, owner); - data << float(BoundsRadius2D); - data << uint32(DecalPropertiesID); - data << *CreatingEffectGUID; - data << *OrbitPathTarget; - data << *RollPitchYaw; - data << int32(PositionalSoundKitID); - data << uint32(MovementStartTime); - data << uint32(CreationTime); - data << float(ZOffset); - data << uint32(Flags); - data << uint32(ScaleCurveId); - data << uint32(FacingCurveId); - data << uint32(MorphCurveId); - data << uint32(MoveCurveId); - data << float(Facing); - data << int32(PathType); - data << uint8(ShapeType); - PeriodModifier->WriteCreate(data, receiver, owner); - if (PathType == 3) - { - PathData.Get()->WriteCreate(data, receiver, owner); - } - if (ShapeType == 0) - { - ShapeData.Get()->WriteCreate(data, receiver, owner); - } - if (ShapeType == 1) - { - ShapeData.Get()->WriteCreate(data, receiver, owner); - } - if (ShapeType == 2 || ShapeType == 3 || ShapeType == 5 || ShapeType == 6) - { - ShapeData.Get()->WriteCreate(data, receiver, owner); - } - if (ShapeType == 4) - { - ShapeData.Get()->WriteCreate(data, receiver, owner); - } - if (ShapeType == 7) - { - ShapeData.Get()->WriteCreate(data, receiver, owner); - } - if (ShapeType == 8) - { - ShapeData.Get()->WriteCreate(data, receiver, owner); - } - ExtraScaleCurve->WriteCreate(data, receiver, owner); - data.FlushBits(); - data.WriteBits(TargetRollPitchYaw.has_value(), 1); - data.WriteBits(ForcedPositionAndRotation.has_value(), 1); - OverrideMoveCurveX->WriteCreate(data, receiver, owner); - if (TargetRollPitchYaw.has_value()) - { - data << *TargetRollPitchYaw; - } - if (ForcedPositionAndRotation.has_value()) - { - ForcedPositionAndRotation->WriteCreate(data, receiver, owner); - } - OverrideMoveCurveY->WriteCreate(data, receiver, owner); - OverrideMoveCurveZ->WriteCreate(data, receiver, owner); - VisualAnim->WriteCreate(data, receiver, owner); - if (PathType == 0) - { - PathData.Get()->WriteCreate(data, receiver, owner); - } - if (PathType == 1) - { - PathData.Get()->WriteCreate(data, receiver, owner); - } -} - -void AreaTriggerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void AreaTriggerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner, bool ignoreNestedChangesMask) const -{ - data << uint32(changesMask.GetBlock(0)); - data.WriteBits(changesMask.GetBlock(1), 5); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - OverrideScaleCurve->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[6]) - { - data << *Caster; - } - if (changesMask[7]) - { - data << uint32(Duration); - } - if (changesMask[8]) - { - data << uint32(TimeToTarget); - } - if (changesMask[9]) - { - data << uint32(TimeToTargetScale); - } - if (changesMask[10]) - { - data << uint32(TimeToTargetExtraScale); - } - if (changesMask[11]) - { - data << uint32(TimeToTargetPos); - } - if (changesMask[12]) - { - data << int32(SpellID); - } - if (changesMask[13]) - { - data << int32(SpellForVisuals); - } - if (changesMask[14]) - { - SpellVisual->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[15]) - { - data << float(BoundsRadius2D); - } - if (changesMask[16]) - { - data << uint32(DecalPropertiesID); - } - if (changesMask[17]) - { - data << *CreatingEffectGUID; - } - if (changesMask[18]) - { - data << *OrbitPathTarget; - } - if (changesMask[19]) - { - data << *RollPitchYaw; - } - if (changesMask[20]) - { - data << int32(PositionalSoundKitID); - } - if (changesMask[21]) - { - data << uint32(MovementStartTime); - } - if (changesMask[22]) - { - data << uint32(CreationTime); - } - if (changesMask[23]) - { - data << float(ZOffset); - } - if (changesMask[25]) - { - data << uint32(Flags); - } - if (changesMask[27]) - { - data << uint32(ScaleCurveId); - } - if (changesMask[28]) - { - data << uint32(FacingCurveId); - } - if (changesMask[29]) - { - data << uint32(MorphCurveId); - } - if (changesMask[30]) - { - data << uint32(MoveCurveId); - } - if (changesMask[31]) - { - data << float(Facing); - } - } - if (changesMask[32]) - { - if (changesMask[34]) - { - data << int32(PathType); - } - if (changesMask[35]) - { - data << uint8(ShapeType); - } - if (changesMask[36]) - { - PeriodModifier->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[34]) - { - if (PathType == 3) - { - PathData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[35]) - { - if (ShapeType == 0) - { - ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (ShapeType == 1) - { - ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (ShapeType == 2 || ShapeType == 3 || ShapeType == 5 || ShapeType == 6) - { - ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (ShapeType == 4) - { - ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (ShapeType == 7) - { - ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (ShapeType == 8) - { - ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[0]) - { - if (changesMask[2]) - { - ExtraScaleCurve->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - data.FlushBits(); - if (changesMask[0]) - { - data.WriteBits(TargetRollPitchYaw.has_value(), 1); - } - if (changesMask[32]) - { - data.WriteBits(ForcedPositionAndRotation.has_value(), 1); - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - OverrideMoveCurveX->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[24]) - { - if (TargetRollPitchYaw.has_value()) - { - data << *TargetRollPitchYaw; - } - } - } - if (changesMask[32]) - { - if (changesMask[33]) - { - if (ForcedPositionAndRotation.has_value()) - { - ForcedPositionAndRotation->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[0]) - { - if (changesMask[4]) - { - OverrideMoveCurveY->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[5]) - { - OverrideMoveCurveZ->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (changesMask[26]) - { - VisualAnim->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - if (changesMask[32]) - { - if (changesMask[34]) - { - if (PathType == 0) - { - PathData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - if (PathType == 1) - { - PathData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } -} - -void AreaTriggerData::ClearChangesMask() -{ - Base::ClearChangesMask(OverrideScaleCurve); - Base::ClearChangesMask(ExtraScaleCurve); - Base::ClearChangesMask(OverrideMoveCurveX); - Base::ClearChangesMask(OverrideMoveCurveY); - Base::ClearChangesMask(OverrideMoveCurveZ); - Base::ClearChangesMask(Caster); - Base::ClearChangesMask(Duration); - Base::ClearChangesMask(TimeToTarget); - Base::ClearChangesMask(TimeToTargetScale); - Base::ClearChangesMask(TimeToTargetExtraScale); - Base::ClearChangesMask(TimeToTargetPos); - Base::ClearChangesMask(SpellID); - Base::ClearChangesMask(SpellForVisuals); - Base::ClearChangesMask(SpellVisual); - Base::ClearChangesMask(BoundsRadius2D); - Base::ClearChangesMask(DecalPropertiesID); - Base::ClearChangesMask(CreatingEffectGUID); - Base::ClearChangesMask(OrbitPathTarget); - Base::ClearChangesMask(RollPitchYaw); - Base::ClearChangesMask(PositionalSoundKitID); - Base::ClearChangesMask(MovementStartTime); - Base::ClearChangesMask(CreationTime); - Base::ClearChangesMask(ZOffset); - Base::ClearChangesMask(TargetRollPitchYaw); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(VisualAnim); - Base::ClearChangesMask(ScaleCurveId); - Base::ClearChangesMask(FacingCurveId); - Base::ClearChangesMask(MorphCurveId); - Base::ClearChangesMask(MoveCurveId); - Base::ClearChangesMask(Facing); - Base::ClearChangesMask(ForcedPositionAndRotation); - Base::ClearChangesMask(PathType); - Base::ClearChangesMask(ShapeType); - Base::ClearChangesMask(PeriodModifier); - Base::ClearChangesMask(PathData); - Base::ClearChangesMask(ShapeData); - _changesMask.ResetAll(); -} - -void SceneObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << int32(ScriptPackageID); - data << uint32(RndSeedVal); - data << *CreatedBy; - data << uint32(SceneType); -} - -void SceneObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void SceneObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 5); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(ScriptPackageID); - } - if (changesMask[2]) - { - data << uint32(RndSeedVal); - } - if (changesMask[3]) - { - data << *CreatedBy; - } - if (changesMask[4]) - { - data << uint32(SceneType); - } - } -} - -void SceneObjectData::ClearChangesMask() -{ - Base::ClearChangesMask(ScriptPackageID); - Base::ClearChangesMask(RndSeedVal); - Base::ClearChangesMask(CreatedBy); - Base::ClearChangesMask(SceneType); - _changesMask.ResetAll(); -} - -void ConversationLine::WriteCreate(ByteBuffer& data, Player const* receiver, Conversation const* owner) const -{ - data << int32(ConversationLineID); - data << int32(BroadcastTextID); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << int32(UiCameraID); - data << uint8(ActorIndex); - data << uint8(Flags); - data << uint8(ChatType); -} - -void ConversationLine::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Conversation const* owner) const -{ - data << int32(ConversationLineID); - data << int32(BroadcastTextID); - data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << int32(UiCameraID); - data << uint8(ActorIndex); - data << uint8(Flags); - data << uint8(ChatType); -} - -bool ConversationLine::operator==(ConversationLine const& right) const -{ - return ConversationLineID == right.ConversationLineID - && BroadcastTextID == right.BroadcastTextID - && StartTime == right.StartTime - && UiCameraID == right.UiCameraID - && ActorIndex == right.ActorIndex - && Flags == right.Flags - && ChatType == right.ChatType; -} - -void ConversationActor::WriteCreate(ByteBuffer& data, Player const* receiver, Conversation const* owner) const -{ - data << uint32(CreatureID); - data << uint32(CreatureDisplayInfoID); - data << ActorGUID; - data << int32(Id); - data.WriteBits(Type, 1); - data.WriteBits(NoActorObject, 1); - data.FlushBits(); -} - -void ConversationActor::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Conversation const* owner) const -{ - data << uint32(CreatureID); - data << uint32(CreatureDisplayInfoID); - data << ActorGUID; - data << int32(Id); - data.WriteBits(Type, 1); - data.WriteBits(NoActorObject, 1); - data.FlushBits(); -} - -bool ConversationActor::operator==(ConversationActor const& right) const -{ - return CreatureID == right.CreatureID - && CreatureDisplayInfoID == right.CreatureDisplayInfoID - && ActorGUID == right.ActorGUID - && Id == right.Id - && Type == right.Type - && NoActorObject == right.NoActorObject; -} - -void ConversationData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Conversation const* owner) const -{ - data << uint32(Lines->size()); - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - data << uint32(Progress); - for (uint32 i = 0; i < Lines->size(); ++i) - { - (*Lines)[i].WriteCreate(data, receiver, owner); - } - data.WriteBit(DontPlayBroadcastTextSounds); - data.WriteBit(Field_33); - data << uint32(Actors.size()); - data << uint32(Flags); - for (uint32 i = 0; i < Actors.size(); ++i) - { - Actors[i].WriteCreate(data, receiver, owner); - } - data.FlushBits(); -} - -void ConversationData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Conversation const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void ConversationData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Conversation const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 8); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(DontPlayBroadcastTextSounds); - } - if (changesMask[2]) - { - data.WriteBit(Field_33); - } - if (changesMask[3]) - { - data.WriteBits(Lines->size(), 32); - for (uint32 i = 0; i < Lines->size(); ++i) - { - (*Lines)[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[4]) - { - if (!ignoreNestedChangesMask) - Actors.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Actors.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[4]) - { - for (uint32 i = 0; i < Actors.size(); ++i) - { - if (Actors.HasChanged(i) || ignoreNestedChangesMask) - { - Actors[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[5]) - { - data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); - } - if (changesMask[6]) - { - data << uint32(Progress); - } - if (changesMask[7]) - { - data << uint32(Flags); - } - } - data.FlushBits(); -} - -void ConversationData::ClearChangesMask() -{ - Base::ClearChangesMask(DontPlayBroadcastTextSounds); - Base::ClearChangesMask(Field_33); - Base::ClearChangesMask(Lines); - Base::ClearChangesMask(Actors); - Base::ClearChangesMask(LastLineEndTime); - Base::ClearChangesMask(Progress); - Base::ClearChangesMask(Flags); - _changesMask.ResetAll(); -} - -void MeshObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data.WriteBit(IsWMO); - data.WriteBit(IsRoom); - data.WriteBits(Geobox.has_value(), 1); - data << int32(FileDataID); - if (Geobox.has_value()) - { - data << *Geobox; - } - data.FlushBits(); - data.FlushBits(); -} - -void MeshObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void MeshObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 5); - - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteBit(IsWMO); - } - if (changesMask[2]) - { - data.WriteBit(IsRoom); - } - data.WriteBits(Geobox.has_value(), 1); - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - data << int32(FileDataID); - } - if (changesMask[4]) - { - if (Geobox.has_value()) - { - data << *Geobox; - } - } - } - data.FlushBits(); -} - -void MeshObjectData::ClearChangesMask() -{ - Base::ClearChangesMask(IsWMO); - Base::ClearChangesMask(IsRoom); - Base::ClearChangesMask(FileDataID); - Base::ClearChangesMask(Geobox); - _changesMask.ResetAll(); -} - -void VendorData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Creature const* owner) const -{ - data << int32(Flags); -} - -void VendorData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Creature const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void VendorData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Creature const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 2); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(Flags); - } - } -} - -void VendorData::ClearChangesMask() -{ - Base::ClearChangesMask(Flags); - _changesMask.ResetAll(); -} - -void DecorDyeSlots::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - for (uint32 i = 0; i < 3; ++i) - { - data << int32(DyeColorID[i]); - } -} - -void DecorDyeSlots::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - for (uint32 i = 0; i < 3; ++i) - { - data << int32(DyeColorID[i]); - } -} - -bool DecorDyeSlots::operator==(DecorDyeSlots const& right) const -{ - return DyeColorID == right.DyeColorID; -} - -void DecorStoragePersistedData::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << *HouseGUID; - data << uint8(SourceType); - data.WriteBits(DyeSlots.has_value(), 1); - data.WriteBits(SourceValue->size() + 1, 24); - data.FlushBits(); - if (DyeSlots.has_value()) - { - DyeSlots->WriteCreate(data, receiver, owner); - } - data << WorldPackets::SizedCString::Data(*SourceValue); -} - -void DecorStoragePersistedData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 4); - - data.FlushBits(); - if (changesMask[0]) - { - data << *HouseGUID; - } - if (changesMask[2]) - { - data << uint8(SourceType); - } - data.WriteBits(DyeSlots.has_value(), 1); - if (changesMask[3]) - { - data.WriteBits(SourceValue->size() + 1, 24); - } - data.FlushBits(); - if (changesMask[1]) - { - if (DyeSlots.has_value()) - { - DyeSlots->WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - } - if (changesMask[3]) - { - data << WorldPackets::SizedCString::Data(*SourceValue); - } -} - -void DecorStoragePersistedData::ClearChangesMask() -{ - Base::ClearChangesMask(HouseGUID); - Base::ClearChangesMask(DyeSlots); - Base::ClearChangesMask(SourceType); - Base::ClearChangesMask(SourceValue); - _changesMask.ResetAll(); -} - -void HousingDecorData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << *DecorGUID; - data << *AttachParentGUID; - data << uint8(Flags); - data << *TargetGameObjectGUID; - data.WriteBits(PersistedData.has_value(), 1); - data.FlushBits(); - if (PersistedData.has_value()) - { - PersistedData->WriteCreate(data, receiver, owner); - } -} - -void HousingDecorData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingDecorData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 6); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *DecorGUID; - } - if (changesMask[2]) - { - data << *AttachParentGUID; - } - if (changesMask[3]) - { - data << uint8(Flags); - } - if (changesMask[5]) - { - data << *TargetGameObjectGUID; - } - data.WriteBits(PersistedData.has_value(), 1); - data.FlushBits(); - if (changesMask[4]) - { - if (PersistedData.has_value()) - { - PersistedData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } -} - -void HousingDecorData::ClearChangesMask() -{ - Base::ClearChangesMask(DecorGUID); - Base::ClearChangesMask(AttachParentGUID); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(PersistedData); - Base::ClearChangesMask(TargetGameObjectGUID); - _changesMask.ResetAll(); -} - -void HousingDoorData::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << int32(RoomComponentID); - data << *RoomComponentOffset; - data << uint8(RoomComponentType); - data << *AttachedRoomGUID; -} - -void HousingDoorData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 5); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << int32(RoomComponentID); - } - if (changesMask[2]) - { - data << *RoomComponentOffset; - } - if (changesMask[3]) - { - data << uint8(RoomComponentType); - } - if (changesMask[4]) - { - data << *AttachedRoomGUID; - } - } -} - -void HousingDoorData::ClearChangesMask() -{ - Base::ClearChangesMask(RoomComponentID); - Base::ClearChangesMask(RoomComponentOffset); - Base::ClearChangesMask(RoomComponentType); - Base::ClearChangesMask(AttachedRoomGUID); - _changesMask.ResetAll(); -} - -void HousingRoomData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << *HouseGUID; - data << int32(HouseRoomID); - data << int32(Flags); - data << uint32(MeshObjects.size()); - data << uint32(Doors.size()); - data << int32(FloorIndex); - for (uint32 i = 0; i < MeshObjects.size(); ++i) - { - data << MeshObjects[i]; - } - for (uint32 i = 0; i < Doors.size(); ++i) - { - Doors[i].WriteCreate(data, receiver, owner); - } -} - -void HousingRoomData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingRoomData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 7); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreNestedChangesMask) - MeshObjects.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(MeshObjects.size(), data); - } - if (changesMask[2]) - { - if (!ignoreNestedChangesMask) - Doors.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Doors.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < MeshObjects.size(); ++i) - { - if (MeshObjects.HasChanged(i) || ignoreNestedChangesMask) - { - data << MeshObjects[i]; - } - } - } - if (changesMask[2]) - { - for (uint32 i = 0; i < Doors.size(); ++i) - { - if (Doors.HasChanged(i) || ignoreNestedChangesMask) - { - Doors[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[3]) - { - data << *HouseGUID; - } - if (changesMask[4]) - { - data << int32(HouseRoomID); - } - if (changesMask[5]) - { - data << int32(Flags); - } - if (changesMask[6]) - { - data << int32(FloorIndex); - } - } -} - -void HousingRoomData::ClearChangesMask() -{ - Base::ClearChangesMask(MeshObjects); - Base::ClearChangesMask(Doors); - Base::ClearChangesMask(HouseGUID); - Base::ClearChangesMask(HouseRoomID); - Base::ClearChangesMask(Flags); - Base::ClearChangesMask(FloorIndex); - _changesMask.ResetAll(); -} - -void HousingRoomComponentMeshData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << *RoomGUID; - data << int32(RoomComponentOptionID); - data << int32(RoomComponentID); - data << uint8(Field_20); - data << uint8(RoomComponentType); - data << int32(Field_24); - data << int32(HouseThemeID); - data << int32(RoomComponentTextureID); - data << int32(RoomComponentTypeParam); -} - -void HousingRoomComponentMeshData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingRoomComponentMeshData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 10); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *RoomGUID; - } - if (changesMask[2]) - { - data << int32(RoomComponentOptionID); - } - if (changesMask[3]) - { - data << int32(RoomComponentID); - } - if (changesMask[4]) - { - data << uint8(Field_20); - } - if (changesMask[5]) - { - data << uint8(RoomComponentType); - } - if (changesMask[6]) - { - data << int32(Field_24); - } - if (changesMask[7]) - { - data << int32(HouseThemeID); - } - if (changesMask[8]) - { - data << int32(RoomComponentTextureID); - } - if (changesMask[9]) - { - data << int32(RoomComponentTypeParam); - } - } -} - -void HousingRoomComponentMeshData::ClearChangesMask() -{ - Base::ClearChangesMask(RoomGUID); - Base::ClearChangesMask(RoomComponentOptionID); - Base::ClearChangesMask(RoomComponentID); - Base::ClearChangesMask(Field_20); - Base::ClearChangesMask(RoomComponentType); - Base::ClearChangesMask(Field_24); - Base::ClearChangesMask(HouseThemeID); - Base::ClearChangesMask(RoomComponentTextureID); - Base::ClearChangesMask(RoomComponentTypeParam); - _changesMask.ResetAll(); -} - -void HousingPlayerHouseData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << *BnetAccount; - data << uint32(HouseType); - data << uint32(HouseSize); - data << int32(PlotIndex); - data << uint32(Level); - data << uint64(Favor); - data << uint32(InteriorDecorPlacementBudget); - data << uint32(ExteriorDecorPlacementBudget); - data << uint32(ExteriorFixtureBudget); - data << uint32(RoomPlacementBudget); - data << *EntityGUID; -} - -void HousingPlayerHouseData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingPlayerHouseData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 12); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *BnetAccount; - } - if (changesMask[2]) - { - data << uint32(HouseType); - } - if (changesMask[3]) - { - data << uint32(HouseSize); - } - if (changesMask[4]) - { - data << int32(PlotIndex); - } - if (changesMask[5]) - { - data << uint32(Level); - } - if (changesMask[6]) - { - data << uint64(Favor); - } - if (changesMask[7]) - { - data << uint32(InteriorDecorPlacementBudget); - } - if (changesMask[8]) - { - data << uint32(ExteriorDecorPlacementBudget); - } - if (changesMask[9]) - { - data << uint32(ExteriorFixtureBudget); - } - if (changesMask[10]) - { - data << uint32(RoomPlacementBudget); - } - if (changesMask[11]) - { - data << *EntityGUID; - } - } -} - -void HousingPlayerHouseData::ClearChangesMask() -{ - Base::ClearChangesMask(BnetAccount); - Base::ClearChangesMask(HouseType); - Base::ClearChangesMask(HouseSize); - Base::ClearChangesMask(PlotIndex); - Base::ClearChangesMask(Level); - Base::ClearChangesMask(Favor); - Base::ClearChangesMask(InteriorDecorPlacementBudget); - Base::ClearChangesMask(ExteriorDecorPlacementBudget); - Base::ClearChangesMask(ExteriorFixtureBudget); - Base::ClearChangesMask(RoomPlacementBudget); - Base::ClearChangesMask(EntityGUID); - _changesMask.ResetAll(); -} - -void HousingCornerstoneData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const -{ - data << uint64(Cost); - data << int32(PlotIndex); -} - -void HousingCornerstoneData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingCornerstoneData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, GameObject const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << uint64(Cost); - } - if (changesMask[2]) - { - data << int32(PlotIndex); - } - } -} - -void HousingCornerstoneData::ClearChangesMask() -{ - Base::ClearChangesMask(Cost); - Base::ClearChangesMask(PlotIndex); - _changesMask.ResetAll(); -} - -void HousingPlotAreaTriggerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - data << uint32(PlotID); - data << *HouseOwnerGUID; - data << *HouseGUID; - data << *HouseOwnerBnetAccountGUID; -} - -void HousingPlotAreaTriggerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingPlotAreaTriggerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 5); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << uint32(PlotID); - } - if (changesMask[2]) - { - data << *HouseOwnerGUID; - } - if (changesMask[3]) - { - data << *HouseGUID; - } - if (changesMask[4]) - { - data << *HouseOwnerBnetAccountGUID; - } - } -} - -void HousingPlotAreaTriggerData::ClearChangesMask() -{ - Base::ClearChangesMask(PlotID); - Base::ClearChangesMask(HouseOwnerGUID); - Base::ClearChangesMask(HouseGUID); - Base::ClearChangesMask(HouseOwnerBnetAccountGUID); - _changesMask.ResetAll(); -} - -void PlayerHouseInfo::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << HouseGUID; - data << OwnerGUID; -} - -void PlayerHouseInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << HouseGUID; - data << OwnerGUID; -} - -bool PlayerHouseInfo::operator==(PlayerHouseInfo const& right) const -{ - return HouseGUID == right.HouseGUID - && OwnerGUID == right.OwnerGUID; -} - -void HousingOwner::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << BnetAccountGUID; - data << PlayerGUID; -} - -void HousingOwner::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << BnetAccountGUID; - data << PlayerGUID; -} - -bool HousingOwner::operator==(HousingOwner const& right) const -{ - return BnetAccountGUID == right.BnetAccountGUID - && PlayerGUID == right.PlayerGUID; -} - -void NeighborhoodMirrorData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data.WriteBits(Name->size() + 1, 8); - data << *OwnerGUID; - data << uint32(Houses.size()); - data << uint32(Managers.size()); - data << WorldPackets::SizedCString::Data(*Name); - for (uint32 i = 0; i < Houses.size(); ++i) - { - Houses[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < Managers.size(); ++i) - { - Managers[i].WriteCreate(data, receiver, owner); - } -} - -void NeighborhoodMirrorData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void NeighborhoodMirrorData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 5); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreNestedChangesMask) - Houses.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Houses.size(), data); - } - if (changesMask[2]) - { - if (!ignoreNestedChangesMask) - Managers.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Managers.size(), data); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - for (uint32 i = 0; i < Houses.size(); ++i) - { - if (Houses.HasChanged(i) || ignoreNestedChangesMask) - { - Houses[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - for (uint32 i = 0; i < Managers.size(); ++i) - { - if (Managers.HasChanged(i) || ignoreNestedChangesMask) - { - Managers[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) - { - data.WriteBits(Name->size() + 1, 8); - } - if (changesMask[4]) { data << *OwnerGUID; } if (changesMask[3]) { - data << WorldPackets::SizedCString::Data(*Name); - } - } -} - -void NeighborhoodMirrorData::ClearChangesMask() -{ - Base::ClearChangesMask(Houses); - Base::ClearChangesMask(Managers); - Base::ClearChangesMask(OwnerGUID); - Base::ClearChangesMask(Name); - _changesMask.ResetAll(); -} - -void MirroredMeshObjectData::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - data << *AttachParentGUID; - data << *PositionLocalSpace; - data << float(RotationLocalSpace->x); - data << float(RotationLocalSpace->y); - data << float(RotationLocalSpace->z); - data << float(RotationLocalSpace->w); - data << float(ScaleLocalSpace); - data << uint8(AttachmentFlags); -} - -void MirroredMeshObjectData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 6); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data << *AttachParentGUID; - } - if (changesMask[2]) - { - data << *PositionLocalSpace; - } - if (changesMask[3]) - { - data << float(RotationLocalSpace->x); - data << float(RotationLocalSpace->y); - data << float(RotationLocalSpace->z); - data << float(RotationLocalSpace->w); + data << int32(ItemID); } if (changesMask[4]) { - data << float(ScaleLocalSpace); + data << uint32(Quantity); } if (changesMask[5]) { - data << uint8(AttachmentFlags); + data << int32(ReagentQuality); + } + data.WriteBits(DataSlotIndex.has_value(), 1); + data.FlushBits(); + if (changesMask[6]) + { + if (DataSlotIndex.has_value()) + { + data << uint8(DataSlotIndex); + } } } -} -void MirroredMeshObjectData::ClearChangesMask() -{ - Base::ClearChangesMask(AttachParentGUID); - Base::ClearChangesMask(PositionLocalSpace); - Base::ClearChangesMask(RotationLocalSpace); - Base::ClearChangesMask(ScaleLocalSpace); - Base::ClearChangesMask(AttachmentFlags); - _changesMask.ResetAll(); -} - -void MirroredPositionData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - PositionData->WriteCreate(data, receiver, owner); -} - -void MirroredPositionData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void MirroredPositionData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 2); - - data.FlushBits(); - if (changesMask[0]) + void CraftingOrderItem::ClearChangesMask() { + Base::ClearChangesMask(OrderItemID); + Base::ClearChangesMask(ItemGUID); + Base::ClearChangesMask(OwnerGUID); + Base::ClearChangesMask(ItemID); + Base::ClearChangesMask(Quantity); + Base::ClearChangesMask(ReagentQuality); + Base::ClearChangesMask(DataSlotIndex); + _changesMask.ResetAll(); + } + + void CraftingOrderCustomer::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << *CustomerGUID; + data << *CustomerAccountGUID; + } + + void CraftingOrderCustomer::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) + { + data << *CustomerGUID; + } if (changesMask[1]) { - PositionData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + data << *CustomerAccountGUID; } } -} -void MirroredPositionData::ClearChangesMask() -{ - Base::ClearChangesMask(PositionData); - _changesMask.ResetAll(); -} - -void PlayerMirrorHouse::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << Guid; - data << NeighborhoodGUID; - data << uint32(Level); - data << uint32(Favor); - data << uint32(InitiativeFavor); - data << int32(InitiativeCycleID); - data << int32(MapID); - data << int32(PlotID); -} - -void PlayerMirrorHouse::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << Guid; - data << NeighborhoodGUID; - data << uint32(Level); - data << uint32(Favor); - data << uint32(InitiativeFavor); - data << int32(InitiativeCycleID); - data << int32(MapID); - data << int32(PlotID); -} - -bool PlayerMirrorHouse::operator==(PlayerMirrorHouse const& right) const -{ - return Guid == right.Guid - && NeighborhoodGUID == right.NeighborhoodGUID - && Level == right.Level - && Favor == right.Favor - && InitiativeFavor == right.InitiativeFavor - && InitiativeCycleID == right.InitiativeCycleID - && MapID == right.MapID - && PlotID == right.PlotID; -} - -void NeighborhoodCharterSignature::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << Guid; -} - -void NeighborhoodCharterSignature::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << Guid; -} - -bool NeighborhoodCharterSignature::operator==(NeighborhoodCharterSignature const& right) const -{ - return Guid == right.Guid; -} - -void NeighborhoodCharter::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << int32(Field_4); - data << uint32(Signatures.size()); - for (uint32 i = 0; i < Signatures.size(); ++i) + void CraftingOrderCustomer::ClearChangesMask() { - Signatures[i].WriteCreate(data, receiver, owner); + Base::ClearChangesMask(CustomerGUID); + Base::ClearChangesMask(CustomerAccountGUID); + _changesMask.ResetAll(); } - data.WriteBits(Name.size() + 1, 8); - data << WorldPackets::SizedCString::Data(Name); -} -void NeighborhoodCharter::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(Field_0); - data << int32(Field_4); - data << uint32(Signatures.size()); - for (uint32 i = 0; i < Signatures.size(); ++i) + void CraftingOrderNpcCustomer::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const { - Signatures[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + data << int64(NpcCraftingOrderCustomerID); + data << int32(RealmAddress); } - data.FlushBits(); - data.WriteBits(Name.size() + 1, 8); - data << WorldPackets::SizedCString::Data(Name); -} -bool NeighborhoodCharter::operator==(NeighborhoodCharter const& right) const -{ - return Signatures == right.Signatures - && Field_0 == right.Field_0 - && Field_4 == right.Field_4 - && Name == right.Name; -} - -void NeighborhoodOwnershipTransfer::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << NeighborhoodGUID; - data << CurrentOwnerGUID; - data.WriteBits(NeighborhoodName.size() + 1, 8); - data.FlushBits(); - data << WorldPackets::SizedCString::Data(NeighborhoodName); -} - -void NeighborhoodOwnershipTransfer::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << NeighborhoodGUID; - data << CurrentOwnerGUID; - data.WriteBits(NeighborhoodName.size() + 1, 8); - data.FlushBits(); - data << WorldPackets::SizedCString::Data(NeighborhoodName); -} - -bool NeighborhoodOwnershipTransfer::operator==(NeighborhoodOwnershipTransfer const& right) const -{ - return NeighborhoodGUID == right.NeighborhoodGUID - && CurrentOwnerGUID == right.CurrentOwnerGUID - && NeighborhoodName == right.NeighborhoodName; -} - -void PlayerHouseInfoComponentData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + void CraftingOrderNpcCustomer::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const { - data << uint32(Field_8.size()); - } - data << uint32(Houses.size()); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - data << uint32(Field_88.size()); - data << uint32(Field_C0.size()); - data << uint32(Field_F8.size()); - data << uint8(EditorMode); - for (uint32 i = 0; i < Field_8.size(); ++i) + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) { - data << Field_8[i]; + data << int64(NpcCraftingOrderCustomerID); } - } - for (uint32 i = 0; i < Houses.size(); ++i) - { - Houses[i].WriteCreate(data, receiver, owner); - } - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - for (uint32 i = 0; i < Field_88.size(); ++i) - { - data << Field_88[i]; - } - for (uint32 i = 0; i < Field_C0.size(); ++i) - { - data << Field_C0[i]; - } - for (uint32 i = 0; i < Field_F8.size(); ++i) - { - data << Field_F8[i]; - } - Charter->WriteCreate(data, receiver, owner); - NeighborhoodOwnershipTransfer->WriteCreate(data, receiver, owner); - } -} - -static constexpr void PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(PlayerHouseInfoComponentData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array{ 0x000001FAu }; -} - -void PlayerHouseInfoComponentData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); -} - -void PlayerHouseInfoComponentData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) -{ - Mask allowedMaskForTarget({ 0x00000005u }); - PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - changesMask &= allowedMaskForTarget; -} - -void PlayerHouseInfoComponentData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask allowedMaskForTarget({ 0x00000005u }); - PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); -} - -void PlayerHouseInfoComponentData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 9); - - if (changesMask[0]) - { if (changesMask[1]) { - if (!ignoreNestedChangesMask) - Field_8.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Field_8.size(), data); - } - if (changesMask[2]) - { - if (!ignoreNestedChangesMask) - Houses.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Houses.size(), data); - } - if (changesMask[3]) - { - if (!ignoreNestedChangesMask) - Field_88.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Field_88.size(), data); - } - if (changesMask[4]) - { - if (!ignoreNestedChangesMask) - Field_C0.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Field_C0.size(), data); - } - if (changesMask[5]) - { - if (!ignoreNestedChangesMask) - Field_F8.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Field_F8.size(), data); + data << int32(RealmAddress); } } - data.FlushBits(); - if (changesMask[0]) + + void CraftingOrderNpcCustomer::ClearChangesMask() { - if (changesMask[1]) + Base::ClearChangesMask(NpcCraftingOrderCustomerID); + Base::ClearChangesMask(RealmAddress); + _changesMask.ResetAll(); + } + + void CraftingOrderData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << uint64(OrderID); + data << int32(SkillLineAbilityID); + data << int32(OrderState); + data << uint8(OrderType); + data << uint8(MinQuality); + data << int64(ExpirationTime); + data << int64(ClaimEndTime); + data << int64(TipAmount); + data << int64(ConsortiumCut); + data << uint32(Flags); + data << *CrafterGUID; + data << *PersonalCrafterGUID; + data << int32(NpcCraftingOrderSetID); + data << int32(NpcTreasureID); + data << uint32(Reagents.size()); + data.WriteBits(CustomerNotes->size(), 10); + data.WriteBits(Customer.has_value(), 1); + data.WriteBits(NpcCustomer.has_value(), 1); + data.WriteBits(OutputItem.has_value(), 1); + data.WriteBits(OutputItemData.has_value(), 1); + data.FlushBits(); + for (uint32 i = 0; i < Reagents.size(); ++i) { - for (uint32 i = 0; i < Field_8.size(); ++i) + Reagents[i].WriteCreate(data, receiver, owner); + } + data << WorldPackets::SizedString::Data(*CustomerNotes); + if (Customer.has_value()) + { + Customer->WriteCreate(data, receiver, owner); + } + if (NpcCustomer.has_value()) + { + NpcCustomer->WriteCreate(data, receiver, owner); + } + if (OutputItem.has_value()) + { + OutputItem->WriteCreate(data, receiver, owner); + } + if (OutputItemData.has_value()) + { + data << *OutputItemData; + } + data.FlushBits(); + } + + void CraftingOrderData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 26); + + if (changesMask[0]) + { + if (changesMask[1]) { - if (Field_8.HasChanged(i) || ignoreNestedChangesMask) - { - data << Field_8[i]; - } + if (!ignoreChangesMask) + Reagents.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Reagents.size(), data); } } - if (changesMask[2]) + data.FlushBits(); + if (changesMask[0]) { - for (uint32 i = 0; i < Houses.size(); ++i) + if (changesMask[1]) { - if (Houses.HasChanged(i) || ignoreNestedChangesMask) + for (uint32 i = 0; i < Reagents.size(); ++i) { - Houses[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + if (Reagents.HasChanged(i) || ignoreChangesMask) + { + Reagents[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } } } - } - if (changesMask[3]) - { - for (uint32 i = 0; i < Field_88.size(); ++i) + if (changesMask[2]) { - if (Field_88.HasChanged(i) || ignoreNestedChangesMask) - { - data << Field_88[i]; - } + data << int32(Field_0); } - } - if (changesMask[4]) - { - for (uint32 i = 0; i < Field_C0.size(); ++i) + if (changesMask[3]) { - if (Field_C0.HasChanged(i) || ignoreNestedChangesMask) - { - data << Field_C0[i]; - } + data << uint64(OrderID); } - } - if (changesMask[5]) - { - for (uint32 i = 0; i < Field_F8.size(); ++i) + if (changesMask[4]) { - if (Field_F8.HasChanged(i) || ignoreNestedChangesMask) - { - data << Field_F8[i]; - } + data << int32(SkillLineAbilityID); + } + if (changesMask[5]) + { + data << int32(OrderState); } - } - if (changesMask[7]) - { - data << uint8(EditorMode); } if (changesMask[6]) { - Charter->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + if (changesMask[7]) + { + data << uint8(OrderType); + } + if (changesMask[8]) + { + data << uint8(MinQuality); + } + if (changesMask[9]) + { + data << int64(ExpirationTime); + } + if (changesMask[10]) + { + data << int64(ClaimEndTime); + } + if (changesMask[11]) + { + data << int64(TipAmount); + } } - if (changesMask[8]) + if (changesMask[12]) { - NeighborhoodOwnershipTransfer->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + if (changesMask[13]) + { + data << int64(ConsortiumCut); + } + if (changesMask[14]) + { + data << uint32(Flags); + } + if (changesMask[15]) + { + data << *CrafterGUID; + } + if (changesMask[16]) + { + data << *PersonalCrafterGUID; + } + if (changesMask[17]) + { + data << int32(NpcCraftingOrderSetID); + } } + if (changesMask[18]) + { + if (changesMask[19]) + { + data << int32(NpcTreasureID); + } + if (changesMask[20]) + { + data.WriteBits(CustomerNotes->size(), 10); + } + data.WriteBits(Customer.has_value(), 1); + data.WriteBits(NpcCustomer.has_value(), 1); + data.WriteBits(OutputItem.has_value(), 1); + } + if (changesMask[24]) + { + data.WriteBits(OutputItemData.has_value(), 1); + } + if (changesMask[18]) + { + if (changesMask[20]) + { + data << WorldPackets::SizedString::Data(*CustomerNotes); + } + if (changesMask[21]) + { + if (Customer.has_value()) + { + Customer->WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + if (changesMask[22]) + { + if (NpcCustomer.has_value()) + { + NpcCustomer->WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + if (changesMask[23]) + { + if (OutputItem.has_value()) + { + OutputItem->WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + if (changesMask[24]) + { + if (changesMask[25]) + { + if (OutputItemData.has_value()) + { + data << *OutputItemData; + } + } + } + data.FlushBits(); } -} -void PlayerHouseInfoComponentData::ClearChangesMask() -{ - Base::ClearChangesMask(Field_8); - Base::ClearChangesMask(Houses); - Base::ClearChangesMask(Field_88); - Base::ClearChangesMask(Field_C0); - Base::ClearChangesMask(Field_F8); - Base::ClearChangesMask(Charter); - Base::ClearChangesMask(EditorMode); - Base::ClearChangesMask(NeighborhoodOwnershipTransfer); - _changesMask.ResetAll(); -} - -void HousingStorageData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - WriteMapFieldCreate(Decor, data, receiver, owner); - data << uint32(DecorMaxOwnedCount); -} - -void HousingStorageData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingStorageData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) + void CraftingOrderData::ClearChangesMask() { + Base::ClearChangesMask(Reagents); + Base::ClearChangesMask(Field_0); + Base::ClearChangesMask(OrderID); + Base::ClearChangesMask(SkillLineAbilityID); + Base::ClearChangesMask(OrderState); + Base::ClearChangesMask(OrderType); + Base::ClearChangesMask(MinQuality); + Base::ClearChangesMask(ExpirationTime); + Base::ClearChangesMask(ClaimEndTime); + Base::ClearChangesMask(TipAmount); + Base::ClearChangesMask(ConsortiumCut); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(CrafterGUID); + Base::ClearChangesMask(PersonalCrafterGUID); + Base::ClearChangesMask(NpcCraftingOrderSetID); + Base::ClearChangesMask(NpcTreasureID); + Base::ClearChangesMask(CustomerNotes); + Base::ClearChangesMask(Customer); + Base::ClearChangesMask(NpcCustomer); + Base::ClearChangesMask(OutputItem); + Base::ClearChangesMask(OutputItemData); + _changesMask.ResetAll(); + } + + void CraftingOrder::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Data->WriteCreate(data, receiver, owner); + data.WriteBits(RecraftItemInfo.has_value(), 1); + data.WriteBits(Enchantments.size(), 4); + data.WriteBits(Gems.size(), 2); + data.FlushBits(); + if (RecraftItemInfo.has_value()) + { + data << *RecraftItemInfo; + } + for (uint32 i = 0; i < Enchantments.size(); ++i) + { + data << Enchantments[i]; + } + for (uint32 i = 0; i < Gems.size(); ++i) + { + data << Gems[i]; + } + data.FlushBits(); + } + + void CraftingOrder::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + if (changesMask[0]) + { + if (!ignoreChangesMask) + Enchantments.WriteUpdateMask(data, 4); + else + WriteCompleteDynamicFieldUpdateMask(Enchantments.size(), data, 4); + } if (changesMask[1]) { - WriteMapFieldUpdate(Decor, ignoreNestedChangesMask, data, receiver, owner); + if (!ignoreChangesMask) + Gems.WriteUpdateMask(data, 2); + else + WriteCompleteDynamicFieldUpdateMask(Gems.size(), data, 2); + } + data.FlushBits(); + if (changesMask[0]) + { + for (uint32 i = 0; i < Enchantments.size(); ++i) + { + if (Enchantments.HasChanged(i) || ignoreChangesMask) + { + data << Enchantments[i]; + } + } + } + if (changesMask[1]) + { + for (uint32 i = 0; i < Gems.size(); ++i) + { + if (Gems.HasChanged(i) || ignoreChangesMask) + { + data << Gems[i]; + } + } } if (changesMask[2]) { - data << uint32(DecorMaxOwnedCount); + Data->WriteUpdate(ignoreChangesMask, data, receiver, owner); } + data.WriteBits(RecraftItemInfo.has_value(), 1); + data.FlushBits(); + if (changesMask[3]) + { + if (RecraftItemInfo.has_value()) + { + data << *RecraftItemInfo; + } + } + data.FlushBits(); } -} -void HousingStorageData::ClearChangesMask() -{ - Base::ClearChangesMask(Decor); - Base::ClearChangesMask(DecorMaxOwnedCount); - _changesMask.ResetAll(); -} - -void HousingFixtureData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - data << int32(ExteriorComponentID); - data << int32(HouseExteriorWmoDataID); - data << int32(ExteriorComponentHookID); - data << *HouseGUID; - data << *AttachParentGUID; - data << *Guid; - data << *GameObjectGUID; - data << uint8(ExteriorComponentType); - data << uint8(Field_59); - data << uint8(Size); -} - -void HousingFixtureData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const -{ - WriteUpdate(_changesMask, data, receiver, owner, false); -} - -void HousingFixtureData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 11); - - data.FlushBits(); - if (changesMask[0]) + void CraftingOrder::ClearChangesMask() { + Base::ClearChangesMask(Enchantments); + Base::ClearChangesMask(Gems); + Base::ClearChangesMask(Data); + Base::ClearChangesMask(RecraftItemInfo); + _changesMask.ResetAll(); + } + + void PersonalCraftingOrderCount::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(ProfessionID); + data << uint32(Count); + } + + void PersonalCraftingOrderCount::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) + { + data << int32(ProfessionID); + } if (changesMask[1]) { - data << int32(ExteriorComponentID); + data << uint32(Count); + } + } + + void PersonalCraftingOrderCount::ClearChangesMask() + { + Base::ClearChangesMask(ProfessionID); + Base::ClearChangesMask(Count); + _changesMask.ResetAll(); + } + + void NPCCraftingOrderInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint64(OrderID); + data << int32(NpcCraftingOrderSetID); + data << int32(NpcTreasureID); + data << int32(NpcCraftingOrderCustomerID); + } + + void NPCCraftingOrderInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + data << uint64(OrderID); + } + if (changesMask[1]) + { + data << int32(NpcCraftingOrderSetID); } if (changesMask[2]) { - data << int32(HouseExteriorWmoDataID); + data << int32(NpcTreasureID); } if (changesMask[3]) { - data << int32(ExteriorComponentHookID); + data << int32(NpcCraftingOrderCustomerID); + } + } + + void NPCCraftingOrderInfo::ClearChangesMask() + { + Base::ClearChangesMask(OrderID); + Base::ClearChangesMask(NpcCraftingOrderSetID); + Base::ClearChangesMask(NpcTreasureID); + Base::ClearChangesMask(NpcCraftingOrderCustomerID); + _changesMask.ResetAll(); + } + + void CategoryCooldownMod::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellCategoryID); + data << int32(ModCooldown); + } + + void CategoryCooldownMod::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellCategoryID); + data << int32(ModCooldown); + } + + bool CategoryCooldownMod::operator==(CategoryCooldownMod const& right) const + { + return SpellCategoryID == right.SpellCategoryID + && ModCooldown == right.ModCooldown; + } + + void WeeklySpellUse::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellCategoryID); + data << uint8(Uses); + } + + void WeeklySpellUse::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(SpellCategoryID); + data << uint8(Uses); + } + + bool WeeklySpellUse::operator==(WeeklySpellUse const& right) const + { + return SpellCategoryID == right.SpellCategoryID + && Uses == right.Uses; + } + + void StablePetInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(PetSlot); + data << uint32(PetNumber); + data << uint32(CreatureID); + data << uint32(DisplayID); + data << uint32(ExperienceLevel); + data << uint8(PetFlags); + data << uint32(Specialization); + data.WriteBits(Name->size(), 8); + data << WorldPackets::SizedString::Data(*Name); + data.FlushBits(); + } + + void StablePetInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 9); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(PetSlot); + } + if (changesMask[2]) + { + data << uint32(PetNumber); + } + if (changesMask[3]) + { + data << uint32(CreatureID); + } + if (changesMask[4]) + { + data << uint32(DisplayID); + } + if (changesMask[5]) + { + data << uint32(ExperienceLevel); + } + if (changesMask[7]) + { + data << uint8(PetFlags); + } + if (changesMask[8]) + { + data << uint32(Specialization); + } + if (changesMask[6]) + { + data.WriteBits(Name->size(), 8); + data << WorldPackets::SizedString::Data(*Name); + } + } + data.FlushBits(); + } + + void StablePetInfo::ClearChangesMask() + { + Base::ClearChangesMask(PetSlot); + Base::ClearChangesMask(PetNumber); + Base::ClearChangesMask(CreatureID); + Base::ClearChangesMask(DisplayID); + Base::ClearChangesMask(ExperienceLevel); + Base::ClearChangesMask(Name); + Base::ClearChangesMask(PetFlags); + Base::ClearChangesMask(Specialization); + _changesMask.ResetAll(); + } + + void StableInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(Pets.size()); + data << *StableMaster; + for (uint32 i = 0; i < Pets.size(); ++i) + { + Pets[i].WriteCreate(data, receiver, owner); + } + } + + void StableInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Pets.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Pets.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Pets.size(); ++i) + { + if (Pets.HasChanged(i) || ignoreChangesMask) + { + Pets[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + data << *StableMaster; + } + } + } + + void StableInfo::ClearChangesMask() + { + Base::ClearChangesMask(Pets); + Base::ClearChangesMask(StableMaster); + _changesMask.ResetAll(); + } + + void CollectableSourceTrackedData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(TargetType); + data << int32(TargetID); + data << int32(CollectableSourceInfoID); + } + + void CollectableSourceTrackedData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(TargetType); + } + if (changesMask[2]) + { + data << int32(TargetID); + } + if (changesMask[3]) + { + data << int32(CollectableSourceInfoID); + } + } + } + + void CollectableSourceTrackedData::ClearChangesMask() + { + Base::ClearChangesMask(TargetType); + Base::ClearChangesMask(TargetID); + Base::ClearChangesMask(CollectableSourceInfoID); + _changesMask.ResetAll(); + } + + void BankTabSettings::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data.WriteBits(Name->size(), 7); + data.WriteBits(Icon->size(), 9); + data.WriteBits(Description->size(), 14); + data << int32(DepositFlags); + data << WorldPackets::SizedString::Data(*Name); + data << WorldPackets::SizedString::Data(*Icon); + data << WorldPackets::SizedString::Data(*Description); + data.FlushBits(); + } + + void BankTabSettings::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + if (changesMask[0]) + { + data.WriteBits(Name->size(), 7); + } + if (changesMask[1]) + { + data.WriteBits(Icon->size(), 9); + } + if (changesMask[2]) + { + data.WriteBits(Description->size(), 14); + } + data.FlushBits(); + if (changesMask[3]) + { + data << int32(DepositFlags); + } + if (changesMask[0]) + { + data << WorldPackets::SizedString::Data(*Name); + } + if (changesMask[1]) + { + data << WorldPackets::SizedString::Data(*Icon); + } + if (changesMask[2]) + { + data << WorldPackets::SizedString::Data(*Description); + } + data.FlushBits(); + } + + void BankTabSettings::ClearChangesMask() + { + Base::ClearChangesMask(Name); + Base::ClearChangesMask(Icon); + Base::ClearChangesMask(Description); + Base::ClearChangesMask(DepositFlags); + _changesMask.ResetAll(); + } + + void WalkInData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(MapID); + data << int64(Field_8); + data << Field_18; + data.WriteBits(Type, 1); + data.FlushBits(); + } + + void WalkInData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(MapID); + data << int64(Field_8); + data << Field_18; + data.WriteBits(Type, 1); + data.FlushBits(); + } + + bool WalkInData::operator==(WalkInData const& right) const + { + return MapID == right.MapID + && Field_8 == right.Field_8 + && Type == right.Type + && Field_18 == right.Field_18; + } + + void DelveData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << uint64(Field_8); + data << int32(Field_10); + data << int32(SpellID); + data << uint32(Owners.size()); + for (uint32 i = 0; i < Owners.size(); ++i) + { + data << Owners[i]; + } + data.WriteBits(Started, 1); + data.FlushBits(); + } + + void DelveData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data.FlushBits(); + data << int32(Field_0); + data << uint64(Field_8); + data << int32(Field_10); + data << int32(SpellID); + data << uint32(Owners.size()); + for (uint32 i = 0; i < Owners.size(); ++i) + { + data << Owners[i]; + } + data.WriteBits(Started, 1); + data.FlushBits(); + } + + bool DelveData::operator==(DelveData const& right) const + { + return Owners == right.Owners + && Field_0 == right.Field_0 + && Field_8 == right.Field_8 + && Field_10 == right.Field_10 + && SpellID == right.SpellID + && Started == right.Started; + } + + void ChallengeModeData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(MapID); + data << int32(InitialPlayerCount); + data << uint64(InstanceID); + data << int64(StartTime); + data << KeystoneOwnerGUID; + data << LeaverGUID; + data << int64(InstanceAbandonVoteCooldown); + data.WriteBits(IsActive, 1); + data.WriteBits(HasRestrictions, 1); + data.WriteBits(CanVoteAbandon, 1); + data.FlushBits(); + } + + void ChallengeModeData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(MapID); + data << int32(InitialPlayerCount); + data << uint64(InstanceID); + data << int64(StartTime); + data << KeystoneOwnerGUID; + data << LeaverGUID; + data << int64(InstanceAbandonVoteCooldown); + data.WriteBits(IsActive, 1); + data.WriteBits(HasRestrictions, 1); + data.WriteBits(CanVoteAbandon, 1); + data.FlushBits(); + } + + bool ChallengeModeData::operator==(ChallengeModeData const& right) const + { + return MapID == right.MapID + && InitialPlayerCount == right.InitialPlayerCount + && InstanceID == right.InstanceID + && StartTime == right.StartTime + && KeystoneOwnerGUID == right.KeystoneOwnerGUID + && LeaverGUID == right.LeaverGUID + && InstanceAbandonVoteCooldown == right.InstanceAbandonVoteCooldown + && IsActive == right.IsActive + && HasRestrictions == right.HasRestrictions + && CanVoteAbandon == right.CanVoteAbandon; + } + + void TransmogOutfitDataInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint8(SetType); + data << uint32(Icon); + data.WriteBits(Name->size(), 8); + data.WriteBit(SituationsEnabled); + data.FlushBits(); + data << WorldPackets::SizedString::Data(*Name); + data.FlushBits(); + } + + void TransmogOutfitDataInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + if (changesMask[0]) + { + data.WriteBit(SituationsEnabled); + } + data.FlushBits(); + if (changesMask[1]) + { + data << uint8(SetType); + } + if (changesMask[3]) + { + data << uint32(Icon); + } + if (changesMask[2]) + { + data.WriteBits(Name->size(), 8); + data << WorldPackets::SizedString::Data(*Name); + } + data.FlushBits(); + } + + void TransmogOutfitDataInfo::ClearChangesMask() + { + Base::ClearChangesMask(SituationsEnabled); + Base::ClearChangesMask(SetType); + Base::ClearChangesMask(Name); + Base::ClearChangesMask(Icon); + _changesMask.ResetAll(); + } + + void TransmogOutfitSituationInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(SituationID); + data << uint32(SpecID); + data << uint32(LoadoutID); + data << uint32(EquipmentSetID); + } + + void TransmogOutfitSituationInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + data << uint32(SituationID); + } + if (changesMask[1]) + { + data << uint32(SpecID); + } + if (changesMask[2]) + { + data << uint32(LoadoutID); + } + if (changesMask[3]) + { + data << uint32(EquipmentSetID); + } + } + + void TransmogOutfitSituationInfo::ClearChangesMask() + { + Base::ClearChangesMask(SituationID); + Base::ClearChangesMask(SpecID); + Base::ClearChangesMask(LoadoutID); + Base::ClearChangesMask(EquipmentSetID); + _changesMask.ResetAll(); + } + + void TransmogOutfitSlotData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int8(Slot); + data << uint8(SlotOption); + data << uint32(ItemModifiedAppearanceID); + data << uint8(AppearanceDisplayType); + data << uint32(SpellItemEnchantmentID); + data << uint8(IllusionDisplayType); + data << uint32(Flags); + } + + void TransmogOutfitSlotData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + data.FlushBits(); + if (changesMask[0]) + { + data << int8(Slot); + } + if (changesMask[1]) + { + data << uint8(SlotOption); + } + if (changesMask[2]) + { + data << uint32(ItemModifiedAppearanceID); + } + if (changesMask[3]) + { + data << uint8(AppearanceDisplayType); } if (changesMask[4]) + { + data << uint32(SpellItemEnchantmentID); + } + if (changesMask[5]) + { + data << uint8(IllusionDisplayType); + } + if (changesMask[6]) + { + data << uint32(Flags); + } + } + + void TransmogOutfitSlotData::ClearChangesMask() + { + Base::ClearChangesMask(Slot); + Base::ClearChangesMask(SlotOption); + Base::ClearChangesMask(ItemModifiedAppearanceID); + Base::ClearChangesMask(AppearanceDisplayType); + Base::ClearChangesMask(SpellItemEnchantmentID); + Base::ClearChangesMask(IllusionDisplayType); + Base::ClearChangesMask(Flags); + _changesMask.ResetAll(); + } + + void TransmogOutfitData::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(Id); + data << uint32(Situations.size()); + data << uint32(Slots.size()); + data << uint32(Flags); + for (uint32 i = 0; i < Situations.size(); ++i) + { + Situations[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < Slots.size(); ++i) + { + Slots[i].WriteCreate(data, receiver, owner); + } + OutfitInfo->WriteCreate(data, receiver, owner); + } + + void TransmogOutfitData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 5); + + if (changesMask[0]) + { + if (!ignoreChangesMask) + Situations.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Situations.size(), data); + } + if (changesMask[1]) + { + if (!ignoreChangesMask) + Slots.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Slots.size(), data); + } + data.FlushBits(); + if (changesMask[0]) + { + for (uint32 i = 0; i < Situations.size(); ++i) + { + if (Situations.HasChanged(i) || ignoreChangesMask) + { + Situations[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + if (changesMask[1]) + { + for (uint32 i = 0; i < Slots.size(); ++i) + { + if (Slots.HasChanged(i) || ignoreChangesMask) + { + Slots[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + data << uint32(Id); + } + if (changesMask[4]) + { + data << uint32(Flags); + } + if (changesMask[3]) + { + OutfitInfo->WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + } + + void TransmogOutfitData::ClearChangesMask() + { + Base::ClearChangesMask(Situations); + Base::ClearChangesMask(Slots); + Base::ClearChangesMask(Id); + Base::ClearChangesMask(OutfitInfo); + Base::ClearChangesMask(Flags); + _changesMask.ResetAll(); + } + + void TransmogOutfitMetadata::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint8(SituationTrigger); + data << uint32(TransmogOutfitID); + data << uint8(StampedOptionMainHand); + data << uint8(StampedOptionOffHand); + data << float(CostMod); + data.WriteBit(Locked); + data.FlushBits(); + } + + void TransmogOutfitMetadata::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint8(SituationTrigger); + data << uint32(TransmogOutfitID); + data << uint8(StampedOptionMainHand); + data << uint8(StampedOptionOffHand); + data << float(CostMod); + data.WriteBit(Locked); + data.FlushBits(); + data.FlushBits(); + } + + bool TransmogOutfitMetadata::operator==(TransmogOutfitMetadata const& right) const + { + return Locked == right.Locked + && SituationTrigger == right.SituationTrigger + && TransmogOutfitID == right.TransmogOutfitID + && StampedOptionMainHand == right.StampedOptionMainHand + && StampedOptionOffHand == right.StampedOptionOffHand + && CostMod == right.CostMod; + } + + void Research::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int16(ResearchProjectID); + } + + void Research::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int16(ResearchProjectID); + } + + bool Research::operator==(Research const& right) const + { + return ResearchProjectID == right.ResearchProjectID; + } + + void ActivePlayerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + for (uint32 i = 0; i < 105; ++i) + { + data << InvSlots[i]; + } + data << *FarsightObject; + data << *SummonedBattlePetGUID; + data << uint32(KnownTitles.size()); + data << uint64(Coinage); + data << uint64(AccountBankCoinage); + data << int32(XP); + data << int32(NextLevelXP); + data << int32(TrialXP); + Skill->WriteCreate(data, receiver, owner); + data << int32(CharacterPoints); + data << int32(MaxTalentTiers); + data << uint32(TrackCreatureMask); + data << float(MainhandExpertise); + data << float(OffhandExpertise); + data << float(RangedExpertise); + data << float(CombatRatingExpertise); + data << float(BlockPercentage); + data << float(DodgePercentage); + data << float(DodgePercentageFromAttribute); + data << float(ParryPercentage); + data << float(ParryPercentageFromAttribute); + data << float(CritPercentage); + data << float(RangedCritPercentage); + data << float(OffhandCritPercentage); + data << float(SpellCritPercentage); + data << int32(ShieldBlock); + data << float(ShieldBlockCritPercentage); + data << float(Mastery); + data << float(Speed); + data << float(Avoidance); + data << float(Sturdiness); + data << int32(Versatility); + data << float(VersatilityBonus); + data << float(PvpPowerDamage); + data << float(PvpPowerHealing); + BitVectors->WriteCreate(data, receiver, owner); + data << uint32(CharacterDataElements.size()); + data << uint32(AccountDataElements.size()); + for (uint32 i = 0; i < 2; ++i) + { + RestInfo[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < 7; ++i) + { + data << int32(ModDamageDonePos[i]); + data << int32(ModDamageDoneNeg[i]); + data << float(ModDamageDonePercent[i]); + data << float(ModHealingDonePercent[i]); + } + data << int32(ModHealingDonePos); + data << float(ModHealingPercent); + data << float(ModPeriodicHealingDonePercent); + for (uint32 i = 0; i < 3; ++i) + { + data << float(WeaponDmgMultipliers[i]); + data << float(WeaponAtkSpeedMultipliers[i]); + } + data << float(ModSpellPowerPercent); + data << float(ModResiliencePercent); + data << float(OverrideSpellPowerByAPPercent); + data << float(OverrideAPBySpellPowerPercent); + data << int32(ModTargetResistance); + data << int32(ModTargetPhysicalResistance); + data << uint32(LocalFlags); + data << uint8(GrantableLevels); + data << uint8(MultiActionBars); + data << uint8(LifetimeMaxRank); + data << uint8(NumRespecs); + data << uint32(PvpMedals); + for (uint32 i = 0; i < 12; ++i) + { + data << uint32(BuybackPrice[i]); + data << int64(BuybackTimestamp[i]); + } + data << uint16(TodayHonorableKills); + data << uint16(YesterdayHonorableKills); + data << uint32(LifetimeHonorableKills); + data << int32(WatchedFactionIndex); + for (uint32 i = 0; i < 32; ++i) + { + data << int32(CombatRatings[i]); + } + data << uint32(PvpInfo.size()); + data << int32(MaxLevel); + data << int32(ScalingPlayerLevelDelta); + data << int32(MaxCreatureScalingLevel); + data << uint8(TransmogCostMinScalingLevel); + for (uint32 i = 0; i < 4; ++i) + { + data << uint32(NoReagentCostMask[i]); + } + data << int32(PetSpellPower); + for (uint32 i = 0; i < 2; ++i) + { + data << int32(ProfessionSkillLine[i]); + } + data << float(UiHitModifier); + data << float(UiSpellHitModifier); + data << int32(HomeRealmTimeOffset); + data << float(ModPetHaste); + data << int8(JailersTowerLevelMax); + data << int8(JailersTowerLevel); + data << uint8(LocalRegenFlags); + data << uint8(AuraVision); + data << uint8(NumBackpackSlots); + data << int32(OverrideSpellsID); + data << uint16(LootSpecID); + data << uint32(OverrideZonePVPType); + for (uint32 i = 0; i < 5; ++i) + { + data << uint32(BagSlotFlags[i]); + } + data << int32(Honor); + data << int32(HonorNextLevel); + data << int32(PerksProgramCurrency); + data << uint8(NumBankSlots); + data << uint8(NumCharacterBankTabs); + data << uint8(NumAccountBankTabs); + for (uint32 i = 0; i < 1; ++i) + { + data << uint32(ResearchSites[i].size()); + data << uint32(ResearchSiteProgress[i].size()); + data << uint32(Research[i].size()); + for (uint32 j = 0; j < ResearchSites[i].size(); ++j) + { + data << uint16(ResearchSites[i][j]); + } + for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) + { + data << uint32(ResearchSiteProgress[i][j]); + } + for (uint32 j = 0; j < Research[i].size(); ++j) + { + Research[i][j].WriteCreate(data, receiver, owner); + } + } + data << uint32(DailyQuestsCompleted.size()); + data << uint32(Field_1328.size()); + data << uint32(AvailableQuestLineXQuestIDs.size()); + data << uint32(Heirlooms.size()); + data << uint32(HeirloomFlags.size()); + data << uint32(Toys.size()); + data << uint32(ToyFlags.size()); + data << uint32(Transmog.size()); + data << uint32(ConditionalTransmog.size()); + data << uint32(SelfResSpells.size()); + data << uint32(RuneforgePowers.size()); + data << uint32(TransmogIllusions.size()); + data << uint32(WarbandScenes.size()); + data << uint32(HouseRooms.size()); + data << uint32(HouseExteriorComponents.size()); + data << uint32(HouseThemes.size()); + data << uint32(HouseRoomComponentTextures.size()); + data << uint32(HouseTypes.size()); + data << uint32(Field_1980.size()); + data << uint32(CharacterRestrictions.size()); + data << uint32(SpellPctModByLabel.size()); + data << uint32(SpellFlatModByLabel.size()); + data << uint32(SpellPctModPVPByLabel.size()); + data << uint32(SpellFlatModPVPByLabel.size()); + data << uint32(MawPowers.size()); + data << uint32(MultiFloorExploration.size()); + data << uint32(RecipeProgression.size()); + data << uint32(ReplayedQuests.size()); + data << uint32(TaskQuests.size()); + data << uint32(DisabledSpells.size()); + data << int32(UiChromieTimeExpansionID); + data << int32(TimerunningSeasonID); + data << int32(TransportServerTime); + data << uint32(WeeklyRewardsPeriodSinceOrigin); + data << int16(DEBUGSoulbindConduitRank); + data << uint32(ActiveCombatTraitConfigID); + data << uint32(CraftingOrders.size()); + data << uint32(PersonalCraftingOrderCounts.size()); + data << uint32(NpcCraftingOrders.size()); + data << uint32(CategoryCooldownMods.size()); + data << uint32(WeeklySpellUses.size()); + for (uint32 i = 0; i < 17; ++i) + { + data << float(ItemUpgradeHighWatermark[i]); + } + data << int32(ItemUpgradeHighOnehandWeaponItemID); + data << int32(ItemUpgradeHighFingerItemID); + data << float(ItemUpgradeHighFingerWatermark); + data << int32(ItemUpgradeHighTrinketItemID); + data << float(ItemUpgradeHighTrinketWatermark); + data << uint64(LootHistoryInstanceID); + data << uint32(TrackedCollectableSources.size()); + data << uint8(RequiredMountCapabilityFlags); + for (uint32 i = 0; i < KnownTitles.size(); ++i) + { + data << uint64(KnownTitles[i]); + } + for (uint32 i = 0; i < CharacterDataElements.size(); ++i) + { + CharacterDataElements[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < AccountDataElements.size(); ++i) + { + AccountDataElements[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i) + { + data << int32(DailyQuestsCompleted[i]); + } + for (uint32 i = 0; i < Field_1328.size(); ++i) + { + data << int32(Field_1328[i]); + } + for (uint32 i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i) + { + data << int32(AvailableQuestLineXQuestIDs[i]); + } + for (uint32 i = 0; i < Heirlooms.size(); ++i) + { + data << int32(Heirlooms[i]); + } + for (uint32 i = 0; i < HeirloomFlags.size(); ++i) + { + data << uint32(HeirloomFlags[i]); + } + for (uint32 i = 0; i < Toys.size(); ++i) + { + data << int32(Toys[i]); + } + for (uint32 i = 0; i < ToyFlags.size(); ++i) + { + data << uint32(ToyFlags[i]); + } + for (uint32 i = 0; i < Transmog.size(); ++i) + { + data << uint32(Transmog[i]); + } + for (uint32 i = 0; i < ConditionalTransmog.size(); ++i) + { + data << int32(ConditionalTransmog[i]); + } + for (uint32 i = 0; i < SelfResSpells.size(); ++i) + { + data << int32(SelfResSpells[i]); + } + for (uint32 i = 0; i < RuneforgePowers.size(); ++i) + { + data << uint32(RuneforgePowers[i]); + } + for (uint32 i = 0; i < TransmogIllusions.size(); ++i) + { + data << uint32(TransmogIllusions[i]); + } + for (uint32 i = 0; i < WarbandScenes.size(); ++i) + { + data << uint32(WarbandScenes[i]); + } + for (uint32 i = 0; i < HouseRooms.size(); ++i) + { + data << uint32(HouseRooms[i]); + } + for (uint32 i = 0; i < HouseExteriorComponents.size(); ++i) + { + data << uint32(HouseExteriorComponents[i]); + } + for (uint32 i = 0; i < HouseThemes.size(); ++i) + { + data << uint32(HouseThemes[i]); + } + for (uint32 i = 0; i < HouseRoomComponentTextures.size(); ++i) + { + data << uint32(HouseRoomComponentTextures[i]); + } + for (uint32 i = 0; i < HouseTypes.size(); ++i) + { + data << uint32(HouseTypes[i]); + } + for (uint32 i = 0; i < Field_1980.size(); ++i) + { + data << int32(Field_1980[i]); + } + for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) + { + SpellPctModByLabel[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) + { + SpellFlatModByLabel[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < SpellPctModPVPByLabel.size(); ++i) + { + SpellPctModPVPByLabel[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < SpellFlatModPVPByLabel.size(); ++i) + { + SpellFlatModPVPByLabel[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < MawPowers.size(); ++i) + { + MawPowers[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) + { + MultiFloorExploration[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < RecipeProgression.size(); ++i) + { + RecipeProgression[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < ReplayedQuests.size(); ++i) + { + ReplayedQuests[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < TaskQuests.size(); ++i) + { + TaskQuests[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < DisabledSpells.size(); ++i) + { + data << int32(DisabledSpells[i]); + } + for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) + { + PersonalCraftingOrderCounts[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i) + { + NpcCraftingOrders[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) + { + CategoryCooldownMods[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) + { + WeeklySpellUses[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) + { + TrackedCollectableSources[i].WriteCreate(data, receiver, owner); + } + data.FlushBits(); + data.WriteBit(BackpackAutoSortDisabled); + data.WriteBit(BackpackSellJunkDisabled); + data.WriteBit(BankAutoSortDisabled); + data.WriteBit(SortBagsRightToLeft); + data.WriteBit(InsertItemsLeftToRight); + data.WriteBit(HasPerksProgramPendingReward); + data.WriteBits(QuestSession.has_value(), 1); + data.WriteBits(PetStable.has_value(), 1); + data.WriteBits(CharacterBankTabSettings.size(), 3); + data.WriteBits(AccountBankTabSettings.size(), 3); + data.WriteBits(WalkInData.has_value(), 1); + data.WriteBits(DelveData.has_value(), 1); + data.WriteBits(ChallengeModeData.has_value(), 1); + data.FlushBits(); + ResearchHistory->WriteCreate(data, receiver, owner); + if (QuestSession.has_value()) + { + QuestSession->WriteCreate(data, receiver, owner); + } + data << *FrozenPerksVendorItem; + LevelLinkInfo->WriteCreate(data, receiver, owner); + data << *DungeonScore; + WriteMapFieldCreate(TraitConfigs, data, receiver, owner); + WriteMapFieldCreate(TransmogOutfits, data, receiver, owner); + ViewedOutfit->WriteCreate(data, receiver, owner); + TransmogMetadata->WriteCreate(data, receiver, owner); + for (uint32 i = 0; i < PvpInfo.size(); ++i) + { + PvpInfo[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) + { + CharacterRestrictions[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < CraftingOrders.size(); ++i) + { + CraftingOrders[i].WriteCreate(data, receiver, owner); + } + if (PetStable.has_value()) + { + PetStable->WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) + { + CharacterBankTabSettings[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) + { + AccountBankTabSettings[i].WriteCreate(data, receiver, owner); + } + if (WalkInData.has_value()) + { + WalkInData->WriteCreate(data, receiver, owner); + } + if (DelveData.has_value()) + { + DelveData->WriteCreate(data, receiver, owner); + } + if (ChallengeModeData.has_value()) + { + ChallengeModeData->WriteCreate(data, receiver, owner); + } + data.FlushBits(); + } + + void ActivePlayerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void ActivePlayerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 13); + for (uint32 i = 0; i < 13; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(BackpackAutoSortDisabled); + } + if (changesMask[2]) + { + data.WriteBit(BackpackSellJunkDisabled); + } + if (changesMask[3]) + { + data.WriteBit(BankAutoSortDisabled); + } + if (changesMask[4]) + { + data.WriteBit(SortBagsRightToLeft); + } + if (changesMask[5]) + { + data.WriteBit(InsertItemsLeftToRight); + } + if (changesMask[6]) + { + data.WriteBit(HasPerksProgramPendingReward); + } + if (changesMask[7]) + { + if (!ignoreNestedChangesMask) + KnownTitles.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(KnownTitles.size(), data); + } + if (changesMask[8]) + { + if (!ignoreNestedChangesMask) + CharacterDataElements.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CharacterDataElements.size(), data); + } + if (changesMask[9]) + { + if (!ignoreNestedChangesMask) + AccountDataElements.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(AccountDataElements.size(), data); + } + if (changesMask[10]) + { + if (!ignoreNestedChangesMask) + PvpInfo.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data); + } + } + if (changesMask[50]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[51]) + { + if (!ignoreNestedChangesMask) + ResearchSites[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSites[i].size(), data); + } + } + } + if (changesMask[52]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[53]) + { + if (!ignoreNestedChangesMask) + ResearchSiteProgress[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress[i].size(), data); + } + } + } + if (changesMask[54]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[55]) + { + if (!ignoreNestedChangesMask) + Research[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Research[i].size(), data); + } + } + } + if (changesMask[50]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[51]) + { + for (uint32 j = 0; j < ResearchSites[i].size(); ++j) + { + if (ResearchSites[i].HasChanged(j) || ignoreNestedChangesMask) + { + data << uint16(ResearchSites[i][j]); + } + } + } + } + } + if (changesMask[52]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[53]) + { + for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) + { + if (ResearchSiteProgress[i].HasChanged(j) || ignoreNestedChangesMask) + { + data << uint32(ResearchSiteProgress[i][j]); + } + } + } + } + } + if (changesMask[54]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[55]) + { + for (uint32 j = 0; j < Research[i].size(); ++j) + { + if (Research[i].HasChanged(j) || ignoreNestedChangesMask) + { + Research[i][j].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[11]) + { + if (!ignoreNestedChangesMask) + DailyQuestsCompleted.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.size(), data); + } + if (changesMask[12]) + { + if (!ignoreNestedChangesMask) + Field_1328.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Field_1328.size(), data); + } + if (changesMask[13]) + { + if (!ignoreNestedChangesMask) + AvailableQuestLineXQuestIDs.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.size(), data); + } + if (changesMask[14]) + { + if (!ignoreNestedChangesMask) + Heirlooms.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Heirlooms.size(), data); + } + if (changesMask[15]) + { + if (!ignoreNestedChangesMask) + HeirloomFlags.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.size(), data); + } + if (changesMask[16]) + { + if (!ignoreNestedChangesMask) + Toys.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Toys.size(), data); + } + if (changesMask[17]) + { + if (!ignoreNestedChangesMask) + ToyFlags.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ToyFlags.size(), data); + } + if (changesMask[18]) + { + if (!ignoreNestedChangesMask) + Transmog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Transmog.size(), data); + } + if (changesMask[19]) + { + if (!ignoreNestedChangesMask) + ConditionalTransmog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.size(), data); + } + if (changesMask[20]) + { + if (!ignoreNestedChangesMask) + SelfResSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SelfResSpells.size(), data); + } + if (changesMask[21]) + { + if (!ignoreNestedChangesMask) + RuneforgePowers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.size(), data); + } + if (changesMask[22]) + { + if (!ignoreNestedChangesMask) + TransmogIllusions.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.size(), data); + } + if (changesMask[23]) + { + if (!ignoreNestedChangesMask) + WarbandScenes.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WarbandScenes.size(), data); + } + if (changesMask[24]) + { + if (!ignoreNestedChangesMask) + HouseRooms.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HouseRooms.size(), data); + } + if (changesMask[25]) + { + if (!ignoreNestedChangesMask) + HouseExteriorComponents.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HouseExteriorComponents.size(), data); + } + if (changesMask[26]) + { + if (!ignoreNestedChangesMask) + HouseThemes.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HouseThemes.size(), data); + } + if (changesMask[27]) + { + if (!ignoreNestedChangesMask) + HouseRoomComponentTextures.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HouseRoomComponentTextures.size(), data); + } + if (changesMask[28]) + { + if (!ignoreNestedChangesMask) + HouseTypes.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HouseTypes.size(), data); + } + if (changesMask[29]) + { + if (!ignoreNestedChangesMask) + Field_1980.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Field_1980.size(), data); + } + if (changesMask[30]) + { + if (!ignoreNestedChangesMask) + CharacterRestrictions.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data); + } + if (changesMask[31]) + { + if (!ignoreNestedChangesMask) + SpellPctModByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data); + } + } + if (changesMask[32]) + { + if (changesMask[33]) + { + if (!ignoreNestedChangesMask) + SpellFlatModByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data); + } + if (changesMask[34]) + { + if (!ignoreNestedChangesMask) + SpellPctModPVPByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellPctModPVPByLabel.size(), data); + } + if (changesMask[35]) + { + if (!ignoreNestedChangesMask) + SpellFlatModPVPByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellFlatModPVPByLabel.size(), data); + } + if (changesMask[36]) + { + if (!ignoreNestedChangesMask) + MawPowers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(MawPowers.size(), data); + } + if (changesMask[37]) + { + if (!ignoreNestedChangesMask) + MultiFloorExploration.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.size(), data); + } + if (changesMask[38]) + { + if (!ignoreNestedChangesMask) + RecipeProgression.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(RecipeProgression.size(), data); + } + if (changesMask[39]) + { + if (!ignoreNestedChangesMask) + ReplayedQuests.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data); + } + if (changesMask[40]) + { + if (!ignoreNestedChangesMask) + TaskQuests.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(TaskQuests.size(), data); + } + if (changesMask[41]) + { + if (!ignoreNestedChangesMask) + DisabledSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data); + } + if (changesMask[42]) + { + if (!ignoreNestedChangesMask) + CraftingOrders.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data); + } + if (changesMask[43]) + { + if (!ignoreNestedChangesMask) + PersonalCraftingOrderCounts.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(PersonalCraftingOrderCounts.size(), data); + } + if (changesMask[44]) + { + if (!ignoreNestedChangesMask) + NpcCraftingOrders.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(NpcCraftingOrders.size(), data); + } + if (changesMask[45]) + { + if (!ignoreNestedChangesMask) + CategoryCooldownMods.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data); + } + if (changesMask[46]) + { + if (!ignoreNestedChangesMask) + WeeklySpellUses.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data); + } + if (changesMask[47]) + { + if (!ignoreNestedChangesMask) + TrackedCollectableSources.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(TrackedCollectableSources.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[7]) + { + for (uint32 i = 0; i < KnownTitles.size(); ++i) + { + if (KnownTitles.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint64(KnownTitles[i]); + } + } + } + if (changesMask[8]) + { + for (uint32 i = 0; i < CharacterDataElements.size(); ++i) + { + if (CharacterDataElements.HasChanged(i) || ignoreNestedChangesMask) + { + CharacterDataElements[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[9]) + { + for (uint32 i = 0; i < AccountDataElements.size(); ++i) + { + if (AccountDataElements.HasChanged(i) || ignoreNestedChangesMask) + { + AccountDataElements[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[11]) + { + for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i) + { + if (DailyQuestsCompleted.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(DailyQuestsCompleted[i]); + } + } + } + if (changesMask[12]) + { + for (uint32 i = 0; i < Field_1328.size(); ++i) + { + if (Field_1328.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(Field_1328[i]); + } + } + } + if (changesMask[13]) + { + for (uint32 i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i) + { + if (AvailableQuestLineXQuestIDs.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(AvailableQuestLineXQuestIDs[i]); + } + } + } + if (changesMask[14]) + { + for (uint32 i = 0; i < Heirlooms.size(); ++i) + { + if (Heirlooms.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(Heirlooms[i]); + } + } + } + if (changesMask[15]) + { + for (uint32 i = 0; i < HeirloomFlags.size(); ++i) + { + if (HeirloomFlags.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(HeirloomFlags[i]); + } + } + } + if (changesMask[16]) + { + for (uint32 i = 0; i < Toys.size(); ++i) + { + if (Toys.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(Toys[i]); + } + } + } + if (changesMask[17]) + { + for (uint32 i = 0; i < ToyFlags.size(); ++i) + { + if (ToyFlags.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(ToyFlags[i]); + } + } + } + if (changesMask[18]) + { + for (uint32 i = 0; i < Transmog.size(); ++i) + { + if (Transmog.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(Transmog[i]); + } + } + } + if (changesMask[19]) + { + for (uint32 i = 0; i < ConditionalTransmog.size(); ++i) + { + if (ConditionalTransmog.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(ConditionalTransmog[i]); + } + } + } + if (changesMask[20]) + { + for (uint32 i = 0; i < SelfResSpells.size(); ++i) + { + if (SelfResSpells.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(SelfResSpells[i]); + } + } + } + if (changesMask[21]) + { + for (uint32 i = 0; i < RuneforgePowers.size(); ++i) + { + if (RuneforgePowers.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(RuneforgePowers[i]); + } + } + } + if (changesMask[22]) + { + for (uint32 i = 0; i < TransmogIllusions.size(); ++i) + { + if (TransmogIllusions.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(TransmogIllusions[i]); + } + } + } + if (changesMask[23]) + { + for (uint32 i = 0; i < WarbandScenes.size(); ++i) + { + if (WarbandScenes.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(WarbandScenes[i]); + } + } + } + if (changesMask[24]) + { + for (uint32 i = 0; i < HouseRooms.size(); ++i) + { + if (HouseRooms.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(HouseRooms[i]); + } + } + } + if (changesMask[25]) + { + for (uint32 i = 0; i < HouseExteriorComponents.size(); ++i) + { + if (HouseExteriorComponents.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(HouseExteriorComponents[i]); + } + } + } + if (changesMask[26]) + { + for (uint32 i = 0; i < HouseThemes.size(); ++i) + { + if (HouseThemes.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(HouseThemes[i]); + } + } + } + if (changesMask[27]) + { + for (uint32 i = 0; i < HouseRoomComponentTextures.size(); ++i) + { + if (HouseRoomComponentTextures.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(HouseRoomComponentTextures[i]); + } + } + } + if (changesMask[28]) + { + for (uint32 i = 0; i < HouseTypes.size(); ++i) + { + if (HouseTypes.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(HouseTypes[i]); + } + } + } + if (changesMask[29]) + { + for (uint32 i = 0; i < Field_1980.size(); ++i) + { + if (Field_1980.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(Field_1980[i]); + } + } + } + if (changesMask[31]) + { + for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) + { + if (SpellPctModByLabel.HasChanged(i) || ignoreNestedChangesMask) + { + SpellPctModByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + if (changesMask[32]) + { + if (changesMask[33]) + { + for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) + { + if (SpellFlatModByLabel.HasChanged(i) || ignoreNestedChangesMask) + { + SpellFlatModByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[34]) + { + for (uint32 i = 0; i < SpellPctModPVPByLabel.size(); ++i) + { + if (SpellPctModPVPByLabel.HasChanged(i) || ignoreNestedChangesMask) + { + SpellPctModPVPByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[35]) + { + for (uint32 i = 0; i < SpellFlatModPVPByLabel.size(); ++i) + { + if (SpellFlatModPVPByLabel.HasChanged(i) || ignoreNestedChangesMask) + { + SpellFlatModPVPByLabel[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[36]) + { + for (uint32 i = 0; i < MawPowers.size(); ++i) + { + if (MawPowers.HasChanged(i) || ignoreNestedChangesMask) + { + MawPowers[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[37]) + { + for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) + { + if (MultiFloorExploration.HasChanged(i) || ignoreNestedChangesMask) + { + MultiFloorExploration[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[38]) + { + for (uint32 i = 0; i < RecipeProgression.size(); ++i) + { + if (RecipeProgression.HasChanged(i) || ignoreNestedChangesMask) + { + RecipeProgression[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[39]) + { + for (uint32 i = 0; i < ReplayedQuests.size(); ++i) + { + if (ReplayedQuests.HasChanged(i) || ignoreNestedChangesMask) + { + ReplayedQuests[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[40]) + { + for (uint32 i = 0; i < TaskQuests.size(); ++i) + { + if (TaskQuests.HasChanged(i) || ignoreNestedChangesMask) + { + TaskQuests[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[41]) + { + for (uint32 i = 0; i < DisabledSpells.size(); ++i) + { + if (DisabledSpells.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(DisabledSpells[i]); + } + } + } + if (changesMask[43]) + { + for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) + { + if (PersonalCraftingOrderCounts.HasChanged(i) || ignoreNestedChangesMask) + { + PersonalCraftingOrderCounts[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[44]) + { + for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i) + { + if (NpcCraftingOrders.HasChanged(i) || ignoreNestedChangesMask) + { + NpcCraftingOrders[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[45]) + { + for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) + { + if (CategoryCooldownMods.HasChanged(i) || ignoreNestedChangesMask) + { + CategoryCooldownMods[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[46]) + { + for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) + { + if (WeeklySpellUses.HasChanged(i) || ignoreNestedChangesMask) + { + WeeklySpellUses[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[47]) + { + for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) + { + if (TrackedCollectableSources.HasChanged(i) || ignoreNestedChangesMask) + { + TrackedCollectableSources[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + data.FlushBits(); + if (changesMask[32]) + { + if (changesMask[48]) + { + if (!ignoreNestedChangesMask) + CharacterBankTabSettings.WriteUpdateMask(data, 3); + else + WriteCompleteDynamicFieldUpdateMask(CharacterBankTabSettings.size(), data, 3); + } + if (changesMask[49]) + { + if (!ignoreNestedChangesMask) + AccountBankTabSettings.WriteUpdateMask(data, 3); + else + WriteCompleteDynamicFieldUpdateMask(AccountBankTabSettings.size(), data, 3); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[10]) + { + for (uint32 i = 0; i < PvpInfo.size(); ++i) + { + if (PvpInfo.HasChanged(i) || ignoreNestedChangesMask) + { + PvpInfo[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[30]) + { + for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) + { + if (CharacterRestrictions.HasChanged(i) || ignoreNestedChangesMask) + { + CharacterRestrictions[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + if (changesMask[32]) + { + if (changesMask[42]) + { + for (uint32 i = 0; i < CraftingOrders.size(); ++i) + { + if (CraftingOrders.HasChanged(i) || ignoreNestedChangesMask) + { + CraftingOrders[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[48]) + { + for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) + { + if (CharacterBankTabSettings.HasChanged(i) || ignoreNestedChangesMask) + { + CharacterBankTabSettings[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[49]) + { + for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) + { + if (AccountBankTabSettings.HasChanged(i) || ignoreNestedChangesMask) + { + AccountBankTabSettings[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[56]) + { + data << *FarsightObject; + } + if (changesMask[57]) + { + data << *SummonedBattlePetGUID; + } + if (changesMask[58]) + { + data << uint64(Coinage); + } + if (changesMask[59]) + { + data << uint64(AccountBankCoinage); + } + if (changesMask[60]) + { + data << int32(XP); + } + if (changesMask[61]) + { + data << int32(NextLevelXP); + } + if (changesMask[62]) + { + data << int32(TrialXP); + } + if (changesMask[63]) + { + Skill->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[64]) + { + data << int32(CharacterPoints); + } + if (changesMask[65]) + { + data << int32(MaxTalentTiers); + } + if (changesMask[66]) + { + data << uint32(TrackCreatureMask); + } + if (changesMask[67]) + { + data << float(MainhandExpertise); + } + if (changesMask[68]) + { + data << float(OffhandExpertise); + } + if (changesMask[69]) + { + data << float(RangedExpertise); + } + } + if (changesMask[70]) + { + if (changesMask[71]) + { + data << float(CombatRatingExpertise); + } + if (changesMask[72]) + { + data << float(BlockPercentage); + } + if (changesMask[73]) + { + data << float(DodgePercentage); + } + if (changesMask[74]) + { + data << float(DodgePercentageFromAttribute); + } + if (changesMask[75]) + { + data << float(ParryPercentage); + } + if (changesMask[76]) + { + data << float(ParryPercentageFromAttribute); + } + if (changesMask[77]) + { + data << float(CritPercentage); + } + if (changesMask[78]) + { + data << float(RangedCritPercentage); + } + if (changesMask[79]) + { + data << float(OffhandCritPercentage); + } + if (changesMask[80]) + { + data << float(SpellCritPercentage); + } + if (changesMask[81]) + { + data << int32(ShieldBlock); + } + if (changesMask[82]) + { + data << float(ShieldBlockCritPercentage); + } + if (changesMask[83]) + { + data << float(Mastery); + } + if (changesMask[84]) + { + data << float(Speed); + } + if (changesMask[85]) + { + data << float(Avoidance); + } + if (changesMask[86]) + { + data << float(Sturdiness); + } + if (changesMask[87]) + { + data << int32(Versatility); + } + if (changesMask[88]) + { + data << float(VersatilityBonus); + } + if (changesMask[89]) + { + data << float(PvpPowerDamage); + } + if (changesMask[90]) + { + data << float(PvpPowerHealing); + } + if (changesMask[91]) + { + BitVectors->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[92]) + { + data << int32(ModHealingDonePos); + } + if (changesMask[93]) + { + data << float(ModHealingPercent); + } + if (changesMask[94]) + { + data << float(ModPeriodicHealingDonePercent); + } + if (changesMask[95]) + { + data << float(ModSpellPowerPercent); + } + if (changesMask[96]) + { + data << float(ModResiliencePercent); + } + if (changesMask[97]) + { + data << float(OverrideSpellPowerByAPPercent); + } + if (changesMask[98]) + { + data << float(OverrideAPBySpellPowerPercent); + } + if (changesMask[99]) + { + data << int32(ModTargetResistance); + } + if (changesMask[100]) + { + data << int32(ModTargetPhysicalResistance); + } + if (changesMask[101]) + { + data << uint32(LocalFlags); + } + } + if (changesMask[102]) + { + if (changesMask[103]) + { + data << uint8(GrantableLevels); + } + if (changesMask[104]) + { + data << uint8(MultiActionBars); + } + if (changesMask[105]) + { + data << uint8(LifetimeMaxRank); + } + if (changesMask[106]) + { + data << uint8(NumRespecs); + } + if (changesMask[107]) + { + data << uint32(PvpMedals); + } + if (changesMask[108]) + { + data << uint16(TodayHonorableKills); + } + if (changesMask[109]) + { + data << uint16(YesterdayHonorableKills); + } + if (changesMask[110]) + { + data << uint32(LifetimeHonorableKills); + } + if (changesMask[111]) + { + data << int32(WatchedFactionIndex); + } + if (changesMask[112]) + { + data << int32(MaxLevel); + } + if (changesMask[113]) + { + data << int32(ScalingPlayerLevelDelta); + } + if (changesMask[114]) + { + data << int32(MaxCreatureScalingLevel); + } + if (changesMask[115]) + { + data << uint8(TransmogCostMinScalingLevel); + } + if (changesMask[116]) + { + data << int32(PetSpellPower); + } + if (changesMask[117]) + { + data << float(UiHitModifier); + } + if (changesMask[118]) + { + data << float(UiSpellHitModifier); + } + if (changesMask[119]) + { + data << int32(HomeRealmTimeOffset); + } + if (changesMask[120]) + { + data << float(ModPetHaste); + } + if (changesMask[121]) + { + data << int8(JailersTowerLevelMax); + } + if (changesMask[122]) + { + data << int8(JailersTowerLevel); + } + if (changesMask[123]) + { + data << uint8(LocalRegenFlags); + } + if (changesMask[124]) + { + data << uint8(AuraVision); + } + if (changesMask[125]) + { + data << uint8(NumBackpackSlots); + } + if (changesMask[126]) + { + data << int32(OverrideSpellsID); + } + if (changesMask[127]) + { + data << uint16(LootSpecID); + } + if (changesMask[128]) + { + data << uint32(OverrideZonePVPType); + } + if (changesMask[129]) + { + data << int32(Honor); + } + if (changesMask[130]) + { + data << int32(HonorNextLevel); + } + if (changesMask[131]) + { + data << int32(PerksProgramCurrency); + } + if (changesMask[132]) + { + data << uint8(NumBankSlots); + } + if (changesMask[133]) + { + data << uint8(NumCharacterBankTabs); + } + } + if (changesMask[134]) + { + if (changesMask[135]) + { + data << uint8(NumAccountBankTabs); + } + if (changesMask[140]) + { + data << int32(UiChromieTimeExpansionID); + } + if (changesMask[141]) + { + data << int32(TimerunningSeasonID); + } + if (changesMask[142]) + { + data << int32(TransportServerTime); + } + if (changesMask[143]) + { + data << uint32(WeeklyRewardsPeriodSinceOrigin); + } + if (changesMask[144]) + { + data << int16(DEBUGSoulbindConduitRank); + } + if (changesMask[147]) + { + data << uint32(ActiveCombatTraitConfigID); + } + if (changesMask[148]) + { + data << int32(ItemUpgradeHighOnehandWeaponItemID); + } + if (changesMask[149]) + { + data << int32(ItemUpgradeHighFingerItemID); + } + if (changesMask[150]) + { + data << float(ItemUpgradeHighFingerWatermark); + } + if (changesMask[151]) + { + data << int32(ItemUpgradeHighTrinketItemID); + } + if (changesMask[152]) + { + data << float(ItemUpgradeHighTrinketWatermark); + } + if (changesMask[153]) + { + data << uint64(LootHistoryInstanceID); + } + if (changesMask[155]) + { + data << uint8(RequiredMountCapabilityFlags); + } + data.WriteBits(QuestSession.has_value(), 1); + data.WriteBits(PetStable.has_value(), 1); + data.WriteBits(WalkInData.has_value(), 1); + data.WriteBits(DelveData.has_value(), 1); + data.WriteBits(ChallengeModeData.has_value(), 1); + } + data.FlushBits(); + if (changesMask[134]) + { + if (changesMask[136]) + { + ResearchHistory->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[138]) + { + if (QuestSession.has_value()) + { + QuestSession->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[137]) + { + data << *FrozenPerksVendorItem; + } + if (changesMask[139]) + { + LevelLinkInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[145]) + { + data << *DungeonScore; + } + if (changesMask[146]) + { + WriteMapFieldUpdate(TraitConfigs, ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[159]) + { + WriteMapFieldUpdate(TransmogOutfits, ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[160]) + { + ViewedOutfit->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[161]) + { + TransmogMetadata->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[154]) + { + if (PetStable.has_value()) + { + PetStable->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[156]) + { + if (WalkInData.has_value()) + { + WalkInData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[157]) + { + if (DelveData.has_value()) + { + DelveData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[158]) + { + if (ChallengeModeData.has_value()) + { + ChallengeModeData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[162]) + { + for (uint32 i = 0; i < 105; ++i) + { + if (changesMask[163 + i]) + { + data << InvSlots[i]; + } + } + } + if (changesMask[268]) + { + for (uint32 i = 0; i < 2; ++i) + { + if (changesMask[269 + i]) + { + RestInfo[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[271]) + { + for (uint32 i = 0; i < 7; ++i) + { + if (changesMask[272 + i]) + { + data << int32(ModDamageDonePos[i]); + } + if (changesMask[279 + i]) + { + data << int32(ModDamageDoneNeg[i]); + } + if (changesMask[286 + i]) + { + data << float(ModDamageDonePercent[i]); + } + if (changesMask[293 + i]) + { + data << float(ModHealingDonePercent[i]); + } + } + } + if (changesMask[300]) + { + for (uint32 i = 0; i < 3; ++i) + { + if (changesMask[301 + i]) + { + data << float(WeaponDmgMultipliers[i]); + } + if (changesMask[304 + i]) + { + data << float(WeaponAtkSpeedMultipliers[i]); + } + } + } + if (changesMask[307]) + { + for (uint32 i = 0; i < 12; ++i) + { + if (changesMask[308 + i]) + { + data << uint32(BuybackPrice[i]); + } + if (changesMask[320 + i]) + { + data << int64(BuybackTimestamp[i]); + } + } + } + if (changesMask[332]) + { + for (uint32 i = 0; i < 32; ++i) + { + if (changesMask[333 + i]) + { + data << int32(CombatRatings[i]); + } + } + } + if (changesMask[365]) + { + for (uint32 i = 0; i < 4; ++i) + { + if (changesMask[366 + i]) + { + data << uint32(NoReagentCostMask[i]); + } + } + } + if (changesMask[370]) + { + for (uint32 i = 0; i < 2; ++i) + { + if (changesMask[371 + i]) + { + data << int32(ProfessionSkillLine[i]); + } + } + } + if (changesMask[373]) + { + for (uint32 i = 0; i < 5; ++i) + { + if (changesMask[374 + i]) + { + data << uint32(BagSlotFlags[i]); + } + } + } + if (changesMask[379]) + { + for (uint32 i = 0; i < 17; ++i) + { + if (changesMask[380 + i]) + { + data << float(ItemUpgradeHighWatermark[i]); + } + } + } + data.FlushBits(); + } + + void ActivePlayerData::ClearChangesMask() + { + Base::ClearChangesMask(BackpackAutoSortDisabled); + Base::ClearChangesMask(BackpackSellJunkDisabled); + Base::ClearChangesMask(BankAutoSortDisabled); + Base::ClearChangesMask(SortBagsRightToLeft); + Base::ClearChangesMask(InsertItemsLeftToRight); + Base::ClearChangesMask(HasPerksProgramPendingReward); + Base::ClearChangesMask(ResearchSites); + Base::ClearChangesMask(ResearchSiteProgress); + Base::ClearChangesMask(Research); + Base::ClearChangesMask(KnownTitles); + Base::ClearChangesMask(CharacterDataElements); + Base::ClearChangesMask(AccountDataElements); + Base::ClearChangesMask(DailyQuestsCompleted); + Base::ClearChangesMask(Field_1328); + Base::ClearChangesMask(AvailableQuestLineXQuestIDs); + Base::ClearChangesMask(Heirlooms); + Base::ClearChangesMask(HeirloomFlags); + Base::ClearChangesMask(Toys); + Base::ClearChangesMask(ToyFlags); + Base::ClearChangesMask(Transmog); + Base::ClearChangesMask(ConditionalTransmog); + Base::ClearChangesMask(SelfResSpells); + Base::ClearChangesMask(RuneforgePowers); + Base::ClearChangesMask(TransmogIllusions); + Base::ClearChangesMask(WarbandScenes); + Base::ClearChangesMask(HouseRooms); + Base::ClearChangesMask(HouseExteriorComponents); + Base::ClearChangesMask(HouseThemes); + Base::ClearChangesMask(HouseRoomComponentTextures); + Base::ClearChangesMask(HouseTypes); + Base::ClearChangesMask(Field_1980); + Base::ClearChangesMask(SpellPctModByLabel); + Base::ClearChangesMask(SpellFlatModByLabel); + Base::ClearChangesMask(SpellPctModPVPByLabel); + Base::ClearChangesMask(SpellFlatModPVPByLabel); + Base::ClearChangesMask(MawPowers); + Base::ClearChangesMask(MultiFloorExploration); + Base::ClearChangesMask(RecipeProgression); + Base::ClearChangesMask(ReplayedQuests); + Base::ClearChangesMask(TaskQuests); + Base::ClearChangesMask(DisabledSpells); + Base::ClearChangesMask(PersonalCraftingOrderCounts); + Base::ClearChangesMask(NpcCraftingOrders); + Base::ClearChangesMask(CategoryCooldownMods); + Base::ClearChangesMask(WeeklySpellUses); + Base::ClearChangesMask(TrackedCollectableSources); + Base::ClearChangesMask(PvpInfo); + Base::ClearChangesMask(CharacterRestrictions); + Base::ClearChangesMask(CraftingOrders); + Base::ClearChangesMask(CharacterBankTabSettings); + Base::ClearChangesMask(AccountBankTabSettings); + Base::ClearChangesMask(FarsightObject); + Base::ClearChangesMask(SummonedBattlePetGUID); + Base::ClearChangesMask(Coinage); + Base::ClearChangesMask(AccountBankCoinage); + Base::ClearChangesMask(XP); + Base::ClearChangesMask(NextLevelXP); + Base::ClearChangesMask(TrialXP); + Base::ClearChangesMask(Skill); + Base::ClearChangesMask(CharacterPoints); + Base::ClearChangesMask(MaxTalentTiers); + Base::ClearChangesMask(TrackCreatureMask); + Base::ClearChangesMask(MainhandExpertise); + Base::ClearChangesMask(OffhandExpertise); + Base::ClearChangesMask(RangedExpertise); + Base::ClearChangesMask(CombatRatingExpertise); + Base::ClearChangesMask(BlockPercentage); + Base::ClearChangesMask(DodgePercentage); + Base::ClearChangesMask(DodgePercentageFromAttribute); + Base::ClearChangesMask(ParryPercentage); + Base::ClearChangesMask(ParryPercentageFromAttribute); + Base::ClearChangesMask(CritPercentage); + Base::ClearChangesMask(RangedCritPercentage); + Base::ClearChangesMask(OffhandCritPercentage); + Base::ClearChangesMask(SpellCritPercentage); + Base::ClearChangesMask(ShieldBlock); + Base::ClearChangesMask(ShieldBlockCritPercentage); + Base::ClearChangesMask(Mastery); + Base::ClearChangesMask(Speed); + Base::ClearChangesMask(Avoidance); + Base::ClearChangesMask(Sturdiness); + Base::ClearChangesMask(Versatility); + Base::ClearChangesMask(VersatilityBonus); + Base::ClearChangesMask(PvpPowerDamage); + Base::ClearChangesMask(PvpPowerHealing); + Base::ClearChangesMask(BitVectors); + Base::ClearChangesMask(ModHealingDonePos); + Base::ClearChangesMask(ModHealingPercent); + Base::ClearChangesMask(ModPeriodicHealingDonePercent); + Base::ClearChangesMask(ModSpellPowerPercent); + Base::ClearChangesMask(ModResiliencePercent); + Base::ClearChangesMask(OverrideSpellPowerByAPPercent); + Base::ClearChangesMask(OverrideAPBySpellPowerPercent); + Base::ClearChangesMask(ModTargetResistance); + Base::ClearChangesMask(ModTargetPhysicalResistance); + Base::ClearChangesMask(LocalFlags); + Base::ClearChangesMask(GrantableLevels); + Base::ClearChangesMask(MultiActionBars); + Base::ClearChangesMask(LifetimeMaxRank); + Base::ClearChangesMask(NumRespecs); + Base::ClearChangesMask(PvpMedals); + Base::ClearChangesMask(TodayHonorableKills); + Base::ClearChangesMask(YesterdayHonorableKills); + Base::ClearChangesMask(LifetimeHonorableKills); + Base::ClearChangesMask(WatchedFactionIndex); + Base::ClearChangesMask(MaxLevel); + Base::ClearChangesMask(ScalingPlayerLevelDelta); + Base::ClearChangesMask(MaxCreatureScalingLevel); + Base::ClearChangesMask(TransmogCostMinScalingLevel); + Base::ClearChangesMask(PetSpellPower); + Base::ClearChangesMask(UiHitModifier); + Base::ClearChangesMask(UiSpellHitModifier); + Base::ClearChangesMask(HomeRealmTimeOffset); + Base::ClearChangesMask(ModPetHaste); + Base::ClearChangesMask(JailersTowerLevelMax); + Base::ClearChangesMask(JailersTowerLevel); + Base::ClearChangesMask(LocalRegenFlags); + Base::ClearChangesMask(AuraVision); + Base::ClearChangesMask(NumBackpackSlots); + Base::ClearChangesMask(OverrideSpellsID); + Base::ClearChangesMask(LootSpecID); + Base::ClearChangesMask(OverrideZonePVPType); + Base::ClearChangesMask(Honor); + Base::ClearChangesMask(HonorNextLevel); + Base::ClearChangesMask(PerksProgramCurrency); + Base::ClearChangesMask(NumBankSlots); + Base::ClearChangesMask(NumCharacterBankTabs); + Base::ClearChangesMask(NumAccountBankTabs); + Base::ClearChangesMask(ResearchHistory); + Base::ClearChangesMask(FrozenPerksVendorItem); + Base::ClearChangesMask(LevelLinkInfo); + Base::ClearChangesMask(QuestSession); + Base::ClearChangesMask(UiChromieTimeExpansionID); + Base::ClearChangesMask(TimerunningSeasonID); + Base::ClearChangesMask(TransportServerTime); + Base::ClearChangesMask(WeeklyRewardsPeriodSinceOrigin); + Base::ClearChangesMask(DEBUGSoulbindConduitRank); + Base::ClearChangesMask(DungeonScore); + Base::ClearChangesMask(TraitConfigs); + Base::ClearChangesMask(ActiveCombatTraitConfigID); + Base::ClearChangesMask(ItemUpgradeHighOnehandWeaponItemID); + Base::ClearChangesMask(ItemUpgradeHighFingerItemID); + Base::ClearChangesMask(ItemUpgradeHighFingerWatermark); + Base::ClearChangesMask(ItemUpgradeHighTrinketItemID); + Base::ClearChangesMask(ItemUpgradeHighTrinketWatermark); + Base::ClearChangesMask(LootHistoryInstanceID); + Base::ClearChangesMask(PetStable); + Base::ClearChangesMask(RequiredMountCapabilityFlags); + Base::ClearChangesMask(WalkInData); + Base::ClearChangesMask(DelveData); + Base::ClearChangesMask(ChallengeModeData); + Base::ClearChangesMask(TransmogOutfits); + Base::ClearChangesMask(ViewedOutfit); + Base::ClearChangesMask(TransmogMetadata); + Base::ClearChangesMask(InvSlots); + Base::ClearChangesMask(RestInfo); + Base::ClearChangesMask(ModDamageDonePos); + Base::ClearChangesMask(ModDamageDoneNeg); + Base::ClearChangesMask(ModDamageDonePercent); + Base::ClearChangesMask(ModHealingDonePercent); + Base::ClearChangesMask(WeaponDmgMultipliers); + Base::ClearChangesMask(WeaponAtkSpeedMultipliers); + Base::ClearChangesMask(BuybackPrice); + Base::ClearChangesMask(BuybackTimestamp); + Base::ClearChangesMask(CombatRatings); + Base::ClearChangesMask(NoReagentCostMask); + Base::ClearChangesMask(ProfessionSkillLine); + Base::ClearChangesMask(BagSlotFlags); + Base::ClearChangesMask(ItemUpgradeHighWatermark); + _changesMask.ResetAll(); + } + + void GameObjectAssistActionData::WriteCreate(ByteBuffer& data, Player const* receiver, GameObject const* owner) const + { + data.WriteBits(PlayerName.size(), 6); + data.WriteBits(MonsterName.size() + 1, 11); + data << uint32(VirtualRealmAddress); + data << uint8(Sex); + data << int64(Time); + data << int32(DelveTier); + data << WorldPackets::SizedString::Data(PlayerName); + data << WorldPackets::SizedCString::Data(MonsterName); + } + + void GameObjectAssistActionData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, GameObject const* owner) const + { + data.WriteBits(PlayerName.size(), 6); + data.WriteBits(MonsterName.size() + 1, 11); + data << uint32(VirtualRealmAddress); + data << uint8(Sex); + data << int64(Time); + data << int32(DelveTier); + data << WorldPackets::SizedString::Data(PlayerName); + data << WorldPackets::SizedCString::Data(MonsterName); + } + + bool GameObjectAssistActionData::operator==(GameObjectAssistActionData const& right) const + { + return PlayerName == right.PlayerName + && MonsterName == right.MonsterName + && VirtualRealmAddress == right.VirtualRealmAddress + && Sex == right.Sex + && Time == right.Time + && DelveTier == right.DelveTier; + } + + void GameObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const + { + ViewerDependentValue::value_type stateWorldEffectIDs = {}; + + data << int32(DisplayID); + data << uint32(SpellVisualID); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); + data << uint32(stateWorldEffectIDs->size()); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) + { + data << uint32((*stateWorldEffectIDs)[i]); + } + data << *CreatedBy; + data << *GuildGUID; + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << float(ParentRotation->x); + data << float(ParentRotation->y); + data << float(ParentRotation->z); + data << float(ParentRotation->w); + data << int32(FactionTemplate); + data << int8(ViewerDependentValue::GetValue(this, receiver, owner)); + data << int8(TypeID); + data << uint8(PercentHealth); + data << uint32(ArtKit); + data << uint32(EnableDoodadSets.size()); + data << uint32(CustomParam); + data << int32(Level); + data << uint32(AnimGroupInstance); + data << uint32(UiWidgetItemID); + data << uint32(UiWidgetItemQuality); + data << uint32(UiWidgetItemCount); + data << uint32(WorldEffects.size()); + for (uint32 i = 0; i < EnableDoodadSets.size(); ++i) + { + data << int32(EnableDoodadSets[i]); + } + for (uint32 i = 0; i < WorldEffects.size(); ++i) + { + data << int32(WorldEffects[i]); + } + data.WriteBits(AssistActionData.has_value(), 1); + data.FlushBits(); + if (AssistActionData.has_value()) + { + AssistActionData->WriteCreate(data, receiver, owner); + } + } + + void GameObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void GameObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, GameObject const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 26); + + ViewerDependentValue::value_type stateWorldEffectIDs = {}; + + if (changesMask[0]) + { + if (changesMask[1]) + { + stateWorldEffectIDs = ViewerDependentValue::GetValue(this, receiver, owner); + data.WriteBits(stateWorldEffectIDs->size(), 32); + for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) + { + data << uint32((*stateWorldEffectIDs)[i]); + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + EnableDoodadSets.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(EnableDoodadSets.size(), data); + } + if (changesMask[3]) + { + if (!ignoreNestedChangesMask) + WorldEffects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WorldEffects.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + for (uint32 i = 0; i < EnableDoodadSets.size(); ++i) + { + if (EnableDoodadSets.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(EnableDoodadSets[i]); + } + } + } + if (changesMask[3]) + { + for (uint32 i = 0; i < WorldEffects.size(); ++i) + { + if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask) + { + data << int32(WorldEffects[i]); + } + } + } + if (changesMask[4]) + { + data << int32(DisplayID); + } + if (changesMask[5]) + { + data << uint32(SpellVisualID); + } + if (changesMask[6]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[7]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[8]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[9]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[10]) + { + data << *CreatedBy; + } + if (changesMask[11]) + { + data << *GuildGUID; + } + if (changesMask[12]) + { + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[13]) + { + data << float(ParentRotation->x); + data << float(ParentRotation->y); + data << float(ParentRotation->z); + data << float(ParentRotation->w); + } + if (changesMask[14]) + { + data << int32(FactionTemplate); + } + if (changesMask[15]) + { + data << int8(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[16]) + { + data << int8(TypeID); + } + if (changesMask[17]) + { + data << uint8(PercentHealth); + } + if (changesMask[18]) + { + data << uint32(ArtKit); + } + if (changesMask[19]) + { + data << uint32(CustomParam); + } + if (changesMask[20]) + { + data << int32(Level); + } + if (changesMask[21]) + { + data << uint32(AnimGroupInstance); + } + if (changesMask[22]) + { + data << uint32(UiWidgetItemID); + } + if (changesMask[23]) + { + data << uint32(UiWidgetItemQuality); + } + if (changesMask[24]) + { + data << uint32(UiWidgetItemCount); + } + data.WriteBits(AssistActionData.has_value(), 1); + data.FlushBits(); + if (changesMask[25]) + { + if (AssistActionData.has_value()) + { + AssistActionData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + + void GameObjectData::ClearChangesMask() + { + Base::ClearChangesMask(StateWorldEffectIDs); + Base::ClearChangesMask(EnableDoodadSets); + Base::ClearChangesMask(WorldEffects); + Base::ClearChangesMask(DisplayID); + Base::ClearChangesMask(SpellVisualID); + Base::ClearChangesMask(StateSpellVisualID); + Base::ClearChangesMask(SpawnTrackingStateAnimID); + Base::ClearChangesMask(SpawnTrackingStateAnimKitID); + Base::ClearChangesMask(StateWorldEffectsQuestObjectiveID); + Base::ClearChangesMask(CreatedBy); + Base::ClearChangesMask(GuildGUID); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(ParentRotation); + Base::ClearChangesMask(FactionTemplate); + Base::ClearChangesMask(State); + Base::ClearChangesMask(TypeID); + Base::ClearChangesMask(PercentHealth); + Base::ClearChangesMask(ArtKit); + Base::ClearChangesMask(CustomParam); + Base::ClearChangesMask(Level); + Base::ClearChangesMask(AnimGroupInstance); + Base::ClearChangesMask(UiWidgetItemID); + Base::ClearChangesMask(UiWidgetItemQuality); + Base::ClearChangesMask(UiWidgetItemCount); + Base::ClearChangesMask(AssistActionData); + _changesMask.ResetAll(); + } + + void DynamicObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, DynamicObject const* owner) const + { + data << *Caster; + data << uint8(Type); + SpellVisual->WriteCreate(data, receiver, owner); + data << int32(SpellID); + data << float(Radius); + data << uint32(CastTime); + } + + void DynamicObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, DynamicObject const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void DynamicObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, DynamicObject const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 7); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *Caster; + } + if (changesMask[2]) + { + data << uint8(Type); + } + if (changesMask[3]) + { + SpellVisual->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[4]) + { + data << int32(SpellID); + } + if (changesMask[5]) + { + data << float(Radius); + } + if (changesMask[6]) + { + data << uint32(CastTime); + } + } + } + + void DynamicObjectData::ClearChangesMask() + { + Base::ClearChangesMask(Caster); + Base::ClearChangesMask(Type); + Base::ClearChangesMask(SpellVisual); + Base::ClearChangesMask(SpellID); + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(CastTime); + _changesMask.ResetAll(); + } + + void CorpseData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Corpse const* owner) const + { + data << uint32(DynamicFlags); + data << *Owner; + data << *PartyGUID; + data << *GuildGUID; + data << uint32(DisplayID); + for (uint32 i = 0; i < 19; ++i) + { + data << uint32(Items[i]); + } + data << uint8(RaceID); + data << uint8(Sex); + data << uint8(Class); + data << uint32(Customizations.size()); + data << uint32(Flags); + data << int32(FactionTemplate); + data << uint32(StateSpellVisualKitID); + for (uint32 i = 0; i < Customizations.size(); ++i) + { + Customizations[i].WriteCreate(data, receiver, owner); + } + } + + void CorpseData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Corpse const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void CorpseData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Corpse const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlocksMask(0), 2); + for (uint32 i = 0; i < 2; ++i) + if (changesMask.GetBlock(i)) + data.WriteBits(changesMask.GetBlock(i), 32); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreNestedChangesMask) + Customizations.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Customizations.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Customizations.size(); ++i) + { + if (Customizations.HasChanged(i) || ignoreNestedChangesMask) + { + Customizations[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + data << uint32(DynamicFlags); + } + if (changesMask[3]) + { + data << *Owner; + } + if (changesMask[4]) + { + data << *PartyGUID; + } + if (changesMask[5]) + { + data << *GuildGUID; + } + if (changesMask[6]) + { + data << uint32(DisplayID); + } + if (changesMask[7]) + { + data << uint8(RaceID); + } + if (changesMask[8]) + { + data << uint8(Sex); + } + if (changesMask[9]) + { + data << uint8(Class); + } + if (changesMask[10]) + { + data << uint32(Flags); + } + if (changesMask[11]) + { + data << int32(FactionTemplate); + } + if (changesMask[12]) + { + data << uint32(StateSpellVisualKitID); + } + } + if (changesMask[13]) + { + for (uint32 i = 0; i < 19; ++i) + { + if (changesMask[14 + i]) + { + data << uint32(Items[i]); + } + } + } + } + + void CorpseData::ClearChangesMask() + { + Base::ClearChangesMask(Customizations); + Base::ClearChangesMask(DynamicFlags); + Base::ClearChangesMask(Owner); + Base::ClearChangesMask(PartyGUID); + Base::ClearChangesMask(GuildGUID); + Base::ClearChangesMask(DisplayID); + Base::ClearChangesMask(RaceID); + Base::ClearChangesMask(Sex); + Base::ClearChangesMask(Class); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(FactionTemplate); + Base::ClearChangesMask(StateSpellVisualKitID); + Base::ClearChangesMask(Items); + _changesMask.ResetAll(); + } + + void ScaleCurve::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << uint32(StartTimeOffset); + for (uint32 i = 0; i < 2; ++i) + { + data << Points[i]; + } + data << uint32(ParameterCurve); + data.WriteBit(OverrideActive); + data.FlushBits(); + } + + void ScaleCurve::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(OverrideActive); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + data << uint32(StartTimeOffset); + } + if (changesMask[3]) + { + data << uint32(ParameterCurve); + } + } + if (changesMask[4]) + { + for (uint32 i = 0; i < 2; ++i) + { + if (changesMask[5 + i]) + { + data << Points[i]; + } + } + } + data.FlushBits(); + } + + void ScaleCurve::ClearChangesMask() + { + Base::ClearChangesMask(OverrideActive); + Base::ClearChangesMask(StartTimeOffset); + Base::ClearChangesMask(ParameterCurve); + Base::ClearChangesMask(Points); + _changesMask.ResetAll(); + } + + void VisualAnim::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data.WriteBits(AnimationDataID.has_value(), 1); + data.WriteBit(IsDecay); + data.FlushBits(); + data << uint32(AnimKitID); + data << uint32(AnimProgress); + if (AnimationDataID.has_value()) + { + data << int16(AnimationDataID); + } + data.FlushBits(); + } + + void VisualAnim::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 5); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(IsDecay); + } + data.WriteBits(AnimationDataID.has_value(), 1); + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + data << uint32(AnimKitID); + } + if (changesMask[4]) + { + data << uint32(AnimProgress); + } + if (changesMask[2]) + { + if (AnimationDataID.has_value()) + { + data << int16(AnimationDataID); + } + } + } + data.FlushBits(); + } + + void VisualAnim::ClearChangesMask() + { + Base::ClearChangesMask(IsDecay); + Base::ClearChangesMask(AnimationDataID); + Base::ClearChangesMask(AnimKitID); + Base::ClearChangesMask(AnimProgress); + _changesMask.ResetAll(); + } + + void ForceSetAreaTriggerPositionAndRotation::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << TriggerGUID; + data << Pos; + data << float(Rotation.x); + data << float(Rotation.y); + data << float(Rotation.z); + data << float(Rotation.w); + } + + void ForceSetAreaTriggerPositionAndRotation::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << TriggerGUID; + data << Pos; + data << float(Rotation.x); + data << float(Rotation.y); + data << float(Rotation.z); + data << float(Rotation.w); + } + + bool ForceSetAreaTriggerPositionAndRotation::operator==(ForceSetAreaTriggerPositionAndRotation const& right) const + { + return TriggerGUID == right.TriggerGUID + && Pos == right.Pos + && Rotation == right.Rotation; + } + + void AreaTriggerActionSetPeriodModifier::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << int32(Field_0); + data << float(Field_4); + } + + void AreaTriggerActionSetPeriodModifier::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(Field_0); + } + if (changesMask[2]) + { + data << float(Field_4); + } + } + } + + void AreaTriggerActionSetPeriodModifier::ClearChangesMask() + { + Base::ClearChangesMask(Field_0); + Base::ClearChangesMask(Field_4); + _changesMask.ResetAll(); + } + + void AreaTriggerSplineCalculator::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data.WriteBits(Points.size(), 16); + data.WriteBit(Catmullrom); + for (uint32 i = 0; i < Points.size(); ++i) + { + data << Points[i]; + } + data.FlushBits(); + } + + void AreaTriggerSplineCalculator::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(Catmullrom); + } + if (changesMask[2]) + { + if (!ignoreChangesMask) + Points.WriteUpdateMask(data, 16); + else + WriteCompleteDynamicFieldUpdateMask(Points.size(), data, 16); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + for (uint32 i = 0; i < Points.size(); ++i) + { + if (Points.HasChanged(i) || ignoreChangesMask) + { + data << Points[i]; + } + } + } + } + data.FlushBits(); + } + + void AreaTriggerSplineCalculator::ClearChangesMask() + { + Base::ClearChangesMask(Catmullrom); + Base::ClearChangesMask(Points); + _changesMask.ResetAll(); + } + + void AreaTriggerOrbit::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << *Center; + data << float(Radius); + data << float(InitialAngle); + data << float(BlendFromRadius); + data << int32(ExtraTimeForBlending); + data.WriteBit(CounterClockwise); + data.FlushBits(); + } + + void AreaTriggerOrbit::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(CounterClockwise); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + data << *Center; + } + if (changesMask[3]) + { + data << float(Radius); + } + if (changesMask[4]) + { + data << float(InitialAngle); + } + if (changesMask[5]) + { + data << float(BlendFromRadius); + } + if (changesMask[6]) + { + data << int32(ExtraTimeForBlending); + } + } + data.FlushBits(); + } + + void AreaTriggerOrbit::ClearChangesMask() + { + Base::ClearChangesMask(CounterClockwise); + Base::ClearChangesMask(Center); + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(InitialAngle); + Base::ClearChangesMask(BlendFromRadius); + Base::ClearChangesMask(ExtraTimeForBlending); + _changesMask.ResetAll(); + } + + void AreaTriggerMovementScript::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << int32(SpellScriptID); + data << *Center; + data << uint32(CreationTime); + } + + void AreaTriggerMovementScript::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(SpellScriptID); + } + if (changesMask[2]) + { + data << *Center; + } + if (changesMask[3]) + { + data << uint32(CreationTime); + } + } + } + + void AreaTriggerMovementScript::ClearChangesMask() + { + Base::ClearChangesMask(SpellScriptID); + Base::ClearChangesMask(Center); + Base::ClearChangesMask(CreationTime); + _changesMask.ResetAll(); + } + + void AreaTriggerSphere::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << float(Radius); + data << float(RadiusTarget); + } + + void AreaTriggerSphere::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << float(Radius); + } + if (changesMask[2]) + { + data << float(RadiusTarget); + } + } + } + + void AreaTriggerSphere::ClearChangesMask() + { + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(RadiusTarget); + _changesMask.ResetAll(); + } + + void AreaTriggerBox::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << *Extents; + data << *ExtentsTarget; + } + + void AreaTriggerBox::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *Extents; + } + if (changesMask[2]) + { + data << *ExtentsTarget; + } + } + } + + void AreaTriggerBox::ClearChangesMask() + { + Base::ClearChangesMask(Extents); + Base::ClearChangesMask(ExtentsTarget); + _changesMask.ResetAll(); + } + + void AreaTriggerPolygon::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << uint32(Vertices.size()); + data << uint32(VerticesTarget.size()); + data << float(Height); + data << float(HeightTarget); + for (uint32 i = 0; i < Vertices.size(); ++i) + { + data << Vertices[i]; + } + for (uint32 i = 0; i < VerticesTarget.size(); ++i) + { + data << VerticesTarget[i]; + } + } + + void AreaTriggerPolygon::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 5); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Vertices.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Vertices.size(), data); + } + if (changesMask[2]) + { + if (!ignoreChangesMask) + VerticesTarget.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(VerticesTarget.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Vertices.size(); ++i) + { + if (Vertices.HasChanged(i) || ignoreChangesMask) + { + data << Vertices[i]; + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < VerticesTarget.size(); ++i) + { + if (VerticesTarget.HasChanged(i) || ignoreChangesMask) + { + data << VerticesTarget[i]; + } + } + } + if (changesMask[3]) + { + data << float(Height); + } + if (changesMask[4]) + { + data << float(HeightTarget); + } + } + } + + void AreaTriggerPolygon::ClearChangesMask() + { + Base::ClearChangesMask(Vertices); + Base::ClearChangesMask(VerticesTarget); + Base::ClearChangesMask(Height); + Base::ClearChangesMask(HeightTarget); + _changesMask.ResetAll(); + } + + void AreaTriggerCylinder::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << float(Radius); + data << float(RadiusTarget); + data << float(Height); + data << float(HeightTarget); + data << float(LocationZOffset); + data << float(LocationZOffsetTarget); + } + + void AreaTriggerCylinder::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << float(Radius); + } + if (changesMask[2]) + { + data << float(RadiusTarget); + } + if (changesMask[3]) + { + data << float(Height); + } + if (changesMask[4]) + { + data << float(HeightTarget); + } + if (changesMask[5]) + { + data << float(LocationZOffset); + } + if (changesMask[6]) + { + data << float(LocationZOffsetTarget); + } + } + } + + void AreaTriggerCylinder::ClearChangesMask() + { + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(RadiusTarget); + Base::ClearChangesMask(Height); + Base::ClearChangesMask(HeightTarget); + Base::ClearChangesMask(LocationZOffset); + Base::ClearChangesMask(LocationZOffsetTarget); + _changesMask.ResetAll(); + } + + void AreaTriggerDisk::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << float(InnerRadius); + data << float(InnerRadiusTarget); + data << float(OuterRadius); + data << float(OuterRadiusTarget); + data << float(Height); + data << float(HeightTarget); + data << float(LocationZOffset); + data << float(LocationZOffsetTarget); + } + + void AreaTriggerDisk::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 9); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << float(InnerRadius); + } + if (changesMask[2]) + { + data << float(InnerRadiusTarget); + } + if (changesMask[3]) + { + data << float(OuterRadius); + } + if (changesMask[4]) + { + data << float(OuterRadiusTarget); + } + if (changesMask[5]) + { + data << float(Height); + } + if (changesMask[6]) + { + data << float(HeightTarget); + } + if (changesMask[7]) + { + data << float(LocationZOffset); + } + if (changesMask[8]) + { + data << float(LocationZOffsetTarget); + } + } + } + + void AreaTriggerDisk::ClearChangesMask() + { + Base::ClearChangesMask(InnerRadius); + Base::ClearChangesMask(InnerRadiusTarget); + Base::ClearChangesMask(OuterRadius); + Base::ClearChangesMask(OuterRadiusTarget); + Base::ClearChangesMask(Height); + Base::ClearChangesMask(HeightTarget); + Base::ClearChangesMask(LocationZOffset); + Base::ClearChangesMask(LocationZOffsetTarget); + _changesMask.ResetAll(); + } + + void AreaTriggerBoundedPlane::WriteCreate(ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << *Extents; + data << *ExtentsTarget; + } + + void AreaTriggerBoundedPlane::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *Extents; + } + if (changesMask[2]) + { + data << *ExtentsTarget; + } + } + } + + void AreaTriggerBoundedPlane::ClearChangesMask() + { + Base::ClearChangesMask(Extents); + Base::ClearChangesMask(ExtentsTarget); + _changesMask.ResetAll(); + } + + void AreaTriggerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + OverrideScaleCurve->WriteCreate(data, receiver, owner); + data << *Caster; + data << uint32(Duration); + data << uint32(TimeToTarget); + data << uint32(TimeToTargetScale); + data << uint32(TimeToTargetExtraScale); + data << uint32(TimeToTargetPos); + data << int32(SpellID); + data << int32(SpellForVisuals); + SpellVisual->WriteCreate(data, receiver, owner); + data << float(BoundsRadius2D); + data << uint32(DecalPropertiesID); + data << *CreatingEffectGUID; + data << *OrbitPathTarget; + data << *RollPitchYaw; + data << int32(PositionalSoundKitID); + data << uint32(MovementStartTime); + data << uint32(CreationTime); + data << float(ZOffset); + data << uint32(Flags); + data << uint32(ScaleCurveId); + data << uint32(FacingCurveId); + data << uint32(MorphCurveId); + data << uint32(MoveCurveId); + data << float(Facing); + data << int32(PathType); + data << uint8(ShapeType); + PeriodModifier->WriteCreate(data, receiver, owner); + if (PathType == 3) + { + PathData.Get()->WriteCreate(data, receiver, owner); + } + if (ShapeType == 0) + { + ShapeData.Get()->WriteCreate(data, receiver, owner); + } + if (ShapeType == 1) + { + ShapeData.Get()->WriteCreate(data, receiver, owner); + } + if (ShapeType == 2 || ShapeType == 3 || ShapeType == 5 || ShapeType == 6) + { + ShapeData.Get()->WriteCreate(data, receiver, owner); + } + if (ShapeType == 4) + { + ShapeData.Get()->WriteCreate(data, receiver, owner); + } + if (ShapeType == 7) + { + ShapeData.Get()->WriteCreate(data, receiver, owner); + } + if (ShapeType == 8) + { + ShapeData.Get()->WriteCreate(data, receiver, owner); + } + ExtraScaleCurve->WriteCreate(data, receiver, owner); + data.FlushBits(); + data.WriteBits(TargetRollPitchYaw.has_value(), 1); + data.WriteBits(ForcedPositionAndRotation.has_value(), 1); + OverrideMoveCurveX->WriteCreate(data, receiver, owner); + if (TargetRollPitchYaw.has_value()) + { + data << *TargetRollPitchYaw; + } + if (ForcedPositionAndRotation.has_value()) + { + ForcedPositionAndRotation->WriteCreate(data, receiver, owner); + } + OverrideMoveCurveY->WriteCreate(data, receiver, owner); + OverrideMoveCurveZ->WriteCreate(data, receiver, owner); + VisualAnim->WriteCreate(data, receiver, owner); + if (PathType == 0) + { + PathData.Get()->WriteCreate(data, receiver, owner); + } + if (PathType == 1) + { + PathData.Get()->WriteCreate(data, receiver, owner); + } + } + + void AreaTriggerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void AreaTriggerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner, bool ignoreNestedChangesMask) const + { + data << uint32(changesMask.GetBlock(0)); + data.WriteBits(changesMask.GetBlock(1), 5); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + OverrideScaleCurve->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[6]) + { + data << *Caster; + } + if (changesMask[7]) + { + data << uint32(Duration); + } + if (changesMask[8]) + { + data << uint32(TimeToTarget); + } + if (changesMask[9]) + { + data << uint32(TimeToTargetScale); + } + if (changesMask[10]) + { + data << uint32(TimeToTargetExtraScale); + } + if (changesMask[11]) + { + data << uint32(TimeToTargetPos); + } + if (changesMask[12]) + { + data << int32(SpellID); + } + if (changesMask[13]) + { + data << int32(SpellForVisuals); + } + if (changesMask[14]) + { + SpellVisual->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[15]) + { + data << float(BoundsRadius2D); + } + if (changesMask[16]) + { + data << uint32(DecalPropertiesID); + } + if (changesMask[17]) + { + data << *CreatingEffectGUID; + } + if (changesMask[18]) + { + data << *OrbitPathTarget; + } + if (changesMask[19]) + { + data << *RollPitchYaw; + } + if (changesMask[20]) + { + data << int32(PositionalSoundKitID); + } + if (changesMask[21]) + { + data << uint32(MovementStartTime); + } + if (changesMask[22]) + { + data << uint32(CreationTime); + } + if (changesMask[23]) + { + data << float(ZOffset); + } + if (changesMask[25]) + { + data << uint32(Flags); + } + if (changesMask[27]) + { + data << uint32(ScaleCurveId); + } + if (changesMask[28]) + { + data << uint32(FacingCurveId); + } + if (changesMask[29]) + { + data << uint32(MorphCurveId); + } + if (changesMask[30]) + { + data << uint32(MoveCurveId); + } + if (changesMask[31]) + { + data << float(Facing); + } + } + if (changesMask[32]) + { + if (changesMask[34]) + { + data << int32(PathType); + } + if (changesMask[35]) + { + data << uint8(ShapeType); + } + if (changesMask[36]) + { + PeriodModifier->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[34]) + { + if (PathType == 3) + { + PathData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[35]) + { + if (ShapeType == 0) + { + ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (ShapeType == 1) + { + ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (ShapeType == 2 || ShapeType == 3 || ShapeType == 5 || ShapeType == 6) + { + ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (ShapeType == 4) + { + ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (ShapeType == 7) + { + ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (ShapeType == 8) + { + ShapeData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[0]) + { + if (changesMask[2]) + { + ExtraScaleCurve->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + data.FlushBits(); + if (changesMask[0]) + { + data.WriteBits(TargetRollPitchYaw.has_value(), 1); + } + if (changesMask[32]) + { + data.WriteBits(ForcedPositionAndRotation.has_value(), 1); + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + OverrideMoveCurveX->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[24]) + { + if (TargetRollPitchYaw.has_value()) + { + data << *TargetRollPitchYaw; + } + } + } + if (changesMask[32]) + { + if (changesMask[33]) + { + if (ForcedPositionAndRotation.has_value()) + { + ForcedPositionAndRotation->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[0]) + { + if (changesMask[4]) + { + OverrideMoveCurveY->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[5]) + { + OverrideMoveCurveZ->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[26]) + { + VisualAnim->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + if (changesMask[32]) + { + if (changesMask[34]) + { + if (PathType == 0) + { + PathData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (PathType == 1) + { + PathData.Get()->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + + void AreaTriggerData::ClearChangesMask() + { + Base::ClearChangesMask(OverrideScaleCurve); + Base::ClearChangesMask(ExtraScaleCurve); + Base::ClearChangesMask(OverrideMoveCurveX); + Base::ClearChangesMask(OverrideMoveCurveY); + Base::ClearChangesMask(OverrideMoveCurveZ); + Base::ClearChangesMask(Caster); + Base::ClearChangesMask(Duration); + Base::ClearChangesMask(TimeToTarget); + Base::ClearChangesMask(TimeToTargetScale); + Base::ClearChangesMask(TimeToTargetExtraScale); + Base::ClearChangesMask(TimeToTargetPos); + Base::ClearChangesMask(SpellID); + Base::ClearChangesMask(SpellForVisuals); + Base::ClearChangesMask(SpellVisual); + Base::ClearChangesMask(BoundsRadius2D); + Base::ClearChangesMask(DecalPropertiesID); + Base::ClearChangesMask(CreatingEffectGUID); + Base::ClearChangesMask(OrbitPathTarget); + Base::ClearChangesMask(RollPitchYaw); + Base::ClearChangesMask(PositionalSoundKitID); + Base::ClearChangesMask(MovementStartTime); + Base::ClearChangesMask(CreationTime); + Base::ClearChangesMask(ZOffset); + Base::ClearChangesMask(TargetRollPitchYaw); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(VisualAnim); + Base::ClearChangesMask(ScaleCurveId); + Base::ClearChangesMask(FacingCurveId); + Base::ClearChangesMask(MorphCurveId); + Base::ClearChangesMask(MoveCurveId); + Base::ClearChangesMask(Facing); + Base::ClearChangesMask(ForcedPositionAndRotation); + Base::ClearChangesMask(PathType); + Base::ClearChangesMask(ShapeType); + Base::ClearChangesMask(PeriodModifier); + Base::ClearChangesMask(PathData); + Base::ClearChangesMask(ShapeData); + _changesMask.ResetAll(); + } + + void SceneObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << int32(ScriptPackageID); + data << uint32(RndSeedVal); + data << *CreatedBy; + data << uint32(SceneType); + } + + void SceneObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void SceneObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 5); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(ScriptPackageID); + } + if (changesMask[2]) + { + data << uint32(RndSeedVal); + } + if (changesMask[3]) + { + data << *CreatedBy; + } + if (changesMask[4]) + { + data << uint32(SceneType); + } + } + } + + void SceneObjectData::ClearChangesMask() + { + Base::ClearChangesMask(ScriptPackageID); + Base::ClearChangesMask(RndSeedVal); + Base::ClearChangesMask(CreatedBy); + Base::ClearChangesMask(SceneType); + _changesMask.ResetAll(); + } + + void ConversationLine::WriteCreate(ByteBuffer& data, Player const* receiver, Conversation const* owner) const + { + data << int32(ConversationLineID); + data << int32(BroadcastTextID); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << int32(UiCameraID); + data << uint8(ActorIndex); + data << uint8(Flags); + data << uint8(ChatType); + } + + void ConversationLine::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Conversation const* owner) const + { + data << int32(ConversationLineID); + data << int32(BroadcastTextID); + data << uint32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << int32(UiCameraID); + data << uint8(ActorIndex); + data << uint8(Flags); + data << uint8(ChatType); + } + + bool ConversationLine::operator==(ConversationLine const& right) const + { + return ConversationLineID == right.ConversationLineID + && BroadcastTextID == right.BroadcastTextID + && StartTime == right.StartTime + && UiCameraID == right.UiCameraID + && ActorIndex == right.ActorIndex + && Flags == right.Flags + && ChatType == right.ChatType; + } + + void ConversationActor::WriteCreate(ByteBuffer& data, Player const* receiver, Conversation const* owner) const + { + data << uint32(CreatureID); + data << uint32(CreatureDisplayInfoID); + data << ActorGUID; + data << int32(Id); + data.WriteBits(Type, 1); + data.WriteBits(NoActorObject, 1); + data.FlushBits(); + } + + void ConversationActor::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Conversation const* owner) const + { + data << uint32(CreatureID); + data << uint32(CreatureDisplayInfoID); + data << ActorGUID; + data << int32(Id); + data.WriteBits(Type, 1); + data.WriteBits(NoActorObject, 1); + data.FlushBits(); + } + + bool ConversationActor::operator==(ConversationActor const& right) const + { + return CreatureID == right.CreatureID + && CreatureDisplayInfoID == right.CreatureDisplayInfoID + && ActorGUID == right.ActorGUID + && Id == right.Id + && Type == right.Type + && NoActorObject == right.NoActorObject; + } + + void ConversationData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Conversation const* owner) const + { + data << uint32(Lines->size()); + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + data << uint32(Progress); + for (uint32 i = 0; i < Lines->size(); ++i) + { + (*Lines)[i].WriteCreate(data, receiver, owner); + } + data.WriteBit(DontPlayBroadcastTextSounds); + data.WriteBit(Field_33); + data << uint32(Actors.size()); + data << uint32(Flags); + for (uint32 i = 0; i < Actors.size(); ++i) + { + Actors[i].WriteCreate(data, receiver, owner); + } + data.FlushBits(); + } + + void ConversationData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Conversation const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void ConversationData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Conversation const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 8); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(DontPlayBroadcastTextSounds); + } + if (changesMask[2]) + { + data.WriteBit(Field_33); + } + if (changesMask[3]) + { + data.WriteBits(Lines->size(), 32); + for (uint32 i = 0; i < Lines->size(); ++i) + { + (*Lines)[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[4]) + { + if (!ignoreNestedChangesMask) + Actors.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Actors.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[4]) + { + for (uint32 i = 0; i < Actors.size(); ++i) + { + if (Actors.HasChanged(i) || ignoreNestedChangesMask) + { + Actors[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[5]) + { + data << int32(ViewerDependentValue::GetValue(this, receiver, owner)); + } + if (changesMask[6]) + { + data << uint32(Progress); + } + if (changesMask[7]) + { + data << uint32(Flags); + } + } + data.FlushBits(); + } + + void ConversationData::ClearChangesMask() + { + Base::ClearChangesMask(DontPlayBroadcastTextSounds); + Base::ClearChangesMask(Field_33); + Base::ClearChangesMask(Lines); + Base::ClearChangesMask(Actors); + Base::ClearChangesMask(LastLineEndTime); + Base::ClearChangesMask(Progress); + Base::ClearChangesMask(Flags); + _changesMask.ResetAll(); + } + + void MeshObjectData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data.WriteBit(IsWMO); + data.WriteBit(IsRoom); + data.WriteBits(Geobox.has_value(), 1); + data << int32(FileDataID); + if (Geobox.has_value()) + { + data << *Geobox; + } + data.FlushBits(); + data.FlushBits(); + } + + void MeshObjectData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void MeshObjectData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 5); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(IsWMO); + } + if (changesMask[2]) + { + data.WriteBit(IsRoom); + } + data.WriteBits(Geobox.has_value(), 1); + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + data << int32(FileDataID); + } + if (changesMask[4]) + { + if (Geobox.has_value()) + { + data << *Geobox; + } + } + } + data.FlushBits(); + } + + void MeshObjectData::ClearChangesMask() + { + Base::ClearChangesMask(IsWMO); + Base::ClearChangesMask(IsRoom); + Base::ClearChangesMask(FileDataID); + Base::ClearChangesMask(Geobox); + _changesMask.ResetAll(); + } + + void VendorData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Creature const* owner) const + { + data << int32(Flags); + } + + void VendorData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Creature const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void VendorData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Creature const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(Flags); + } + } + } + + void VendorData::ClearChangesMask() + { + Base::ClearChangesMask(Flags); + _changesMask.ResetAll(); + } + + void DecorDyeSlots::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + for (uint32 i = 0; i < 3; ++i) + { + data << int32(DyeColorID[i]); + } + } + + void DecorDyeSlots::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + for (uint32 i = 0; i < 3; ++i) + { + data << int32(DyeColorID[i]); + } + } + + bool DecorDyeSlots::operator==(DecorDyeSlots const& right) const + { + return DyeColorID == right.DyeColorID; + } + + void DecorStoragePersistedData::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << *HouseGUID; + data << uint8(SourceType); + data.WriteBits(DyeSlots.has_value(), 1); + data.WriteBits(SourceValue->size() + 1, 24); + data.FlushBits(); + if (DyeSlots.has_value()) + { + DyeSlots->WriteCreate(data, receiver, owner); + } + data << WorldPackets::SizedCString::Data(*SourceValue); + } + + void DecorStoragePersistedData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) { data << *HouseGUID; } - if (changesMask[5]) - { - data << *AttachParentGUID; - } - if (changesMask[6]) - { - data << *Guid; - } - if (changesMask[7]) - { - data << *GameObjectGUID; - } - if (changesMask[8]) - { - data << uint8(ExteriorComponentType); - } - if (changesMask[9]) - { - data << uint8(Field_59); - } - if (changesMask[10]) - { - data << uint8(Size); - } - } -} - -void HousingFixtureData::ClearChangesMask() -{ - Base::ClearChangesMask(ExteriorComponentID); - Base::ClearChangesMask(HouseExteriorWmoDataID); - Base::ClearChangesMask(ExteriorComponentHookID); - Base::ClearChangesMask(HouseGUID); - Base::ClearChangesMask(AttachParentGUID); - Base::ClearChangesMask(Guid); - Base::ClearChangesMask(GameObjectGUID); - Base::ClearChangesMask(ExteriorComponentType); - Base::ClearChangesMask(Field_59); - Base::ClearChangesMask(Size); - _changesMask.ResetAll(); -} - -void PlayerInitiativeInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int64(RemainingDuration); - data << int32(CurrentInitiativeID); - data << int32(CurrentMilestoneID); - data << int32(CurrentCycleID); - data << float(ProgressRequired); - data << float(CurrentProgress); - data << float(PlayerTotalContribution); -} - -void PlayerInitiativeInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 7); - - data.FlushBits(); - if (changesMask[0]) - { - data << int64(RemainingDuration); - } - if (changesMask[1]) - { - data << int32(CurrentInitiativeID); - } - if (changesMask[2]) - { - data << int32(CurrentMilestoneID); - } - if (changesMask[3]) - { - data << int32(CurrentCycleID); - } - if (changesMask[4]) - { - data << float(ProgressRequired); - } - if (changesMask[5]) - { - data << float(CurrentProgress); - } - if (changesMask[6]) - { - data << float(PlayerTotalContribution); - } -} - -void PlayerInitiativeInfo::ClearChangesMask() -{ - Base::ClearChangesMask(RemainingDuration); - Base::ClearChangesMask(CurrentInitiativeID); - Base::ClearChangesMask(CurrentMilestoneID); - Base::ClearChangesMask(CurrentCycleID); - Base::ClearChangesMask(ProgressRequired); - Base::ClearChangesMask(CurrentProgress); - Base::ClearChangesMask(PlayerTotalContribution); - _changesMask.ResetAll(); -} - -void PlayerInitiativeTaskInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int32(TaskID); - data << int32(TimesCompleted); -} - -void PlayerInitiativeTaskInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 2); - - data.FlushBits(); - if (changesMask[0]) - { - data << int32(TaskID); - } - if (changesMask[1]) - { - data << int32(TimesCompleted); - } -} - -void PlayerInitiativeTaskInfo::ClearChangesMask() -{ - Base::ClearChangesMask(TaskID); - Base::ClearChangesMask(TimesCompleted); - _changesMask.ResetAll(); -} - -void NICompletedMilestoneEntry::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int64(AwardDate); - data << uint32(MilestoneID); -} - -void NICompletedMilestoneEntry::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << int64(AwardDate); - data << uint32(MilestoneID); -} - -bool NICompletedMilestoneEntry::operator==(NICompletedMilestoneEntry const& right) const -{ - return AwardDate == right.AwardDate - && MilestoneID == right.MilestoneID; -} - -void NICompletedInitiativesEntry::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(InitiativeID); - data << uint32(CompletedMilestones.size()); - for (uint32 i = 0; i < CompletedMilestones.size(); ++i) - { - CompletedMilestones[i].WriteCreate(data, receiver, owner); - } - data.WriteBit(Completed); - data.FlushBits(); -} - -void NICompletedInitiativesEntry::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << uint32(InitiativeID); - data << uint32(CompletedMilestones.size()); - for (uint32 i = 0; i < CompletedMilestones.size(); ++i) - { - CompletedMilestones[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); - } - data.FlushBits(); - data.FlushBits(); - data.WriteBit(Completed); - data.FlushBits(); -} - -bool NICompletedInitiativesEntry::operator==(NICompletedInitiativesEntry const& right) const -{ - return Completed == right.Completed - && CompletedMilestones == right.CompletedMilestones - && InitiativeID == right.InitiativeID; -} - -void PlayerInitiativeComponentData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - data << *NeighborhoodGUID; - InitiativeInfo->WriteCreate(data, receiver, owner); - data << uint32(CompletedTasks.size()); - data << uint32(CompletedInitiatives.size()); - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - { - WriteSetFieldCreate(Houses, data, receiver, owner); - } - for (uint32 i = 0; i < CompletedTasks.size(); ++i) - { - CompletedTasks[i].WriteCreate(data, receiver, owner); - } - for (uint32 i = 0; i < CompletedInitiatives.size(); ++i) - { - CompletedInitiatives[i].WriteCreate(data, receiver, owner); - } -} - -static constexpr void PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(PlayerInitiativeComponentData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array{ 0x00000020u }; -} - -void PlayerInitiativeComponentData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) -{ - PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); -} - -void PlayerInitiativeComponentData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) -{ - Mask allowedMaskForTarget({ 0x0000001Fu }); - PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - changesMask &= allowedMaskForTarget; -} - -void PlayerInitiativeComponentData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const -{ - Mask allowedMaskForTarget({ 0x0000001Fu }); - PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); -} - -void PlayerInitiativeComponentData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const -{ - data.WriteBits(changesMask.GetBlock(0), 6); - - if (changesMask[0]) - { - if (changesMask[1]) - { - if (!ignoreNestedChangesMask) - CompletedTasks.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CompletedTasks.size(), data); - } if (changesMask[2]) { - if (!ignoreNestedChangesMask) - CompletedInitiatives.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CompletedInitiatives.size(), data); + data << uint8(SourceType); } - } - data.FlushBits(); - if (changesMask[0]) - { + data.WriteBits(DyeSlots.has_value(), 1); + if (changesMask[3]) + { + data.WriteBits(SourceValue->size() + 1, 24); + } + data.FlushBits(); if (changesMask[1]) { - for (uint32 i = 0; i < CompletedTasks.size(); ++i) + if (DyeSlots.has_value()) { - if (CompletedTasks.HasChanged(i) || ignoreNestedChangesMask) - { - CompletedTasks[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } - } - } - if (changesMask[2]) - { - for (uint32 i = 0; i < CompletedInitiatives.size(); ++i) - { - if (CompletedInitiatives.HasChanged(i) || ignoreNestedChangesMask) - { - CompletedInitiatives[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); - } + DyeSlots->WriteUpdate(ignoreChangesMask, data, receiver, owner); } } if (changesMask[3]) { - data << *NeighborhoodGUID; + data << WorldPackets::SizedCString::Data(*SourceValue); + } + } + + void DecorStoragePersistedData::ClearChangesMask() + { + Base::ClearChangesMask(HouseGUID); + Base::ClearChangesMask(DyeSlots); + Base::ClearChangesMask(SourceType); + Base::ClearChangesMask(SourceValue); + _changesMask.ResetAll(); + } + + void HousingDecorData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << *DecorGUID; + data << *AttachParentGUID; + data << uint8(Flags); + data << *TargetGameObjectGUID; + data.WriteBits(PersistedData.has_value(), 1); + data.FlushBits(); + if (PersistedData.has_value()) + { + PersistedData->WriteCreate(data, receiver, owner); + } + } + + void HousingDecorData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingDecorData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 6); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *DecorGUID; + } + if (changesMask[2]) + { + data << *AttachParentGUID; + } + if (changesMask[3]) + { + data << uint8(Flags); + } + if (changesMask[5]) + { + data << *TargetGameObjectGUID; + } + data.WriteBits(PersistedData.has_value(), 1); + data.FlushBits(); + if (changesMask[4]) + { + if (PersistedData.has_value()) + { + PersistedData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + + void HousingDecorData::ClearChangesMask() + { + Base::ClearChangesMask(DecorGUID); + Base::ClearChangesMask(AttachParentGUID); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(PersistedData); + Base::ClearChangesMask(TargetGameObjectGUID); + _changesMask.ResetAll(); + } + + void HousingDoorData::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << int32(RoomComponentID); + data << *RoomComponentOffset; + data << uint8(RoomComponentType); + data << *AttachedRoomGUID; + } + + void HousingDoorData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 5); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(RoomComponentID); + } + if (changesMask[2]) + { + data << *RoomComponentOffset; + } + if (changesMask[3]) + { + data << uint8(RoomComponentType); + } + if (changesMask[4]) + { + data << *AttachedRoomGUID; + } + } + } + + void HousingDoorData::ClearChangesMask() + { + Base::ClearChangesMask(RoomComponentID); + Base::ClearChangesMask(RoomComponentOffset); + Base::ClearChangesMask(RoomComponentType); + Base::ClearChangesMask(AttachedRoomGUID); + _changesMask.ResetAll(); + } + + void HousingRoomData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << *HouseGUID; + data << int32(HouseRoomID); + data << int32(Flags); + data << uint32(MeshObjects.size()); + data << uint32(Doors.size()); + data << int32(FloorIndex); + for (uint32 i = 0; i < MeshObjects.size(); ++i) + { + data << MeshObjects[i]; + } + for (uint32 i = 0; i < Doors.size(); ++i) + { + Doors[i].WriteCreate(data, receiver, owner); + } + } + + void HousingRoomData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingRoomData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 7); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreNestedChangesMask) + MeshObjects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(MeshObjects.size(), data); + } + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + Doors.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Doors.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < MeshObjects.size(); ++i) + { + if (MeshObjects.HasChanged(i) || ignoreNestedChangesMask) + { + data << MeshObjects[i]; + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < Doors.size(); ++i) + { + if (Doors.HasChanged(i) || ignoreNestedChangesMask) + { + Doors[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[3]) + { + data << *HouseGUID; + } + if (changesMask[4]) + { + data << int32(HouseRoomID); + } + if (changesMask[5]) + { + data << int32(Flags); + } + if (changesMask[6]) + { + data << int32(FloorIndex); + } + } + } + + void HousingRoomData::ClearChangesMask() + { + Base::ClearChangesMask(MeshObjects); + Base::ClearChangesMask(Doors); + Base::ClearChangesMask(HouseGUID); + Base::ClearChangesMask(HouseRoomID); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(FloorIndex); + _changesMask.ResetAll(); + } + + void HousingRoomComponentMeshData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << *RoomGUID; + data << int32(RoomComponentOptionID); + data << int32(RoomComponentID); + data << uint8(Field_20); + data << uint8(RoomComponentType); + data << int32(Field_24); + data << int32(HouseThemeID); + data << int32(RoomComponentTextureID); + data << int32(RoomComponentTypeParam); + } + + void HousingRoomComponentMeshData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingRoomComponentMeshData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 10); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *RoomGUID; + } + if (changesMask[2]) + { + data << int32(RoomComponentOptionID); + } + if (changesMask[3]) + { + data << int32(RoomComponentID); + } + if (changesMask[4]) + { + data << uint8(Field_20); + } + if (changesMask[5]) + { + data << uint8(RoomComponentType); + } + if (changesMask[6]) + { + data << int32(Field_24); + } + if (changesMask[7]) + { + data << int32(HouseThemeID); + } + if (changesMask[8]) + { + data << int32(RoomComponentTextureID); + } + if (changesMask[9]) + { + data << int32(RoomComponentTypeParam); + } + } + } + + void HousingRoomComponentMeshData::ClearChangesMask() + { + Base::ClearChangesMask(RoomGUID); + Base::ClearChangesMask(RoomComponentOptionID); + Base::ClearChangesMask(RoomComponentID); + Base::ClearChangesMask(Field_20); + Base::ClearChangesMask(RoomComponentType); + Base::ClearChangesMask(Field_24); + Base::ClearChangesMask(HouseThemeID); + Base::ClearChangesMask(RoomComponentTextureID); + Base::ClearChangesMask(RoomComponentTypeParam); + _changesMask.ResetAll(); + } + + void HousingPlayerHouseData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + // IDA-verified wire order: BnetAccount, PlotIndex, Level, Favor, 4 budgets, EntityGUID (64 bytes) + data << *BnetAccount; + data << int32(PlotIndex); + data << uint32(Level); + data << uint64(Favor); + data << uint32(InteriorDecorPlacementBudget); + data << uint32(ExteriorDecorPlacementBudget); + data << uint32(RoomPlacementBudget); + data << uint32(ExteriorFixtureBudget); + data << *EntityGUID; + } + + void HousingPlayerHouseData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingPlayerHouseData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 10); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *BnetAccount; + } + if (changesMask[2]) + { + data << int32(PlotIndex); + } + if (changesMask[3]) + { + data << uint32(Level); + } + if (changesMask[4]) + { + data << uint64(Favor); + } + if (changesMask[5]) + { + data << uint32(InteriorDecorPlacementBudget); + } + if (changesMask[6]) + { + data << uint32(ExteriorDecorPlacementBudget); + } + if (changesMask[7]) + { + data << uint32(RoomPlacementBudget); + } + if (changesMask[8]) + { + data << uint32(ExteriorFixtureBudget); + } + if (changesMask[9]) + { + data << *EntityGUID; + } + } + } + + void HousingPlayerHouseData::ClearChangesMask() + { + Base::ClearChangesMask(BnetAccount); + Base::ClearChangesMask(PlotIndex); + Base::ClearChangesMask(Level); + Base::ClearChangesMask(Favor); + Base::ClearChangesMask(InteriorDecorPlacementBudget); + Base::ClearChangesMask(ExteriorDecorPlacementBudget); + Base::ClearChangesMask(RoomPlacementBudget); + Base::ClearChangesMask(ExteriorFixtureBudget); + Base::ClearChangesMask(EntityGUID); + _changesMask.ResetAll(); + } + + void HousingCornerstoneData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const + { + data << uint64(Cost); + data << int32(PlotIndex); + } + + void HousingCornerstoneData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, GameObject const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingCornerstoneData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, GameObject const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint64(Cost); + } + if (changesMask[2]) + { + data << int32(PlotIndex); + } + } + } + + void HousingCornerstoneData::ClearChangesMask() + { + Base::ClearChangesMask(Cost); + Base::ClearChangesMask(PlotIndex); + _changesMask.ResetAll(); + } + + void HousingPlotAreaTriggerData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + data << uint32(PlotID); + data << *HouseOwnerGUID; + data << *HouseGUID; + data << *HouseOwnerBnetAccountGUID; + } + + void HousingPlotAreaTriggerData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingPlotAreaTriggerData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, AreaTrigger const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 5); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(PlotID); + } + if (changesMask[2]) + { + data << *HouseOwnerGUID; + } + if (changesMask[3]) + { + data << *HouseGUID; + } + if (changesMask[4]) + { + data << *HouseOwnerBnetAccountGUID; + } + } + } + + void HousingPlotAreaTriggerData::ClearChangesMask() + { + Base::ClearChangesMask(PlotID); + Base::ClearChangesMask(HouseOwnerGUID); + Base::ClearChangesMask(HouseGUID); + Base::ClearChangesMask(HouseOwnerBnetAccountGUID); + _changesMask.ResetAll(); + } + + void PlayerHouseInfo::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << HouseGUID; + data << OwnerGUID; + } + + void PlayerHouseInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << HouseGUID; + data << OwnerGUID; + } + + bool PlayerHouseInfo::operator==(PlayerHouseInfo const& right) const + { + return HouseGUID == right.HouseGUID + && OwnerGUID == right.OwnerGUID; + } + + void HousingOwner::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << BnetAccountGUID; + data << PlayerGUID; + } + + void HousingOwner::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << BnetAccountGUID; + data << PlayerGUID; + } + + bool HousingOwner::operator==(HousingOwner const& right) const + { + return BnetAccountGUID == right.BnetAccountGUID + && PlayerGUID == right.PlayerGUID; + } + + void NeighborhoodMirrorData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data.WriteBits(Name->size() + 1, 8); + data << *OwnerGUID; + data << uint32(Houses.size()); + data << uint32(Managers.size()); + data << WorldPackets::SizedCString::Data(*Name); + for (uint32 i = 0; i < Houses.size(); ++i) + { + Houses[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < Managers.size(); ++i) + { + Managers[i].WriteCreate(data, receiver, owner); + } + } + + void NeighborhoodMirrorData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void NeighborhoodMirrorData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 5); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreNestedChangesMask) + Houses.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Houses.size(), data); + } + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + Managers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Managers.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Houses.size(); ++i) + { + if (Houses.HasChanged(i) || ignoreNestedChangesMask) + { + Houses[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < Managers.size(); ++i) + { + if (Managers.HasChanged(i) || ignoreNestedChangesMask) + { + Managers[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) + { + data.WriteBits(Name->size() + 1, 8); + } + if (changesMask[4]) + { + data << *OwnerGUID; + } + if (changesMask[3]) + { + data << WorldPackets::SizedCString::Data(*Name); + } + } + } + + void NeighborhoodMirrorData::ClearChangesMask() + { + Base::ClearChangesMask(Houses); + Base::ClearChangesMask(Managers); + Base::ClearChangesMask(OwnerGUID); + Base::ClearChangesMask(Name); + _changesMask.ResetAll(); + } + + void MirroredMeshObjectData::WriteCreate(ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + data << *AttachParentGUID; + data << *PositionLocalSpace; + data << float(RotationLocalSpace->x); + data << float(RotationLocalSpace->y); + data << float(RotationLocalSpace->z); + data << float(RotationLocalSpace->w); + data << float(ScaleLocalSpace); + data << uint8(AttachmentFlags); + } + + void MirroredMeshObjectData::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 6); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *AttachParentGUID; + } + if (changesMask[2]) + { + data << *PositionLocalSpace; + } + if (changesMask[3]) + { + data << float(RotationLocalSpace->x); + data << float(RotationLocalSpace->y); + data << float(RotationLocalSpace->z); + data << float(RotationLocalSpace->w); + } + if (changesMask[4]) + { + data << float(ScaleLocalSpace); + } + if (changesMask[5]) + { + data << uint8(AttachmentFlags); + } + } + } + + void MirroredMeshObjectData::ClearChangesMask() + { + Base::ClearChangesMask(AttachParentGUID); + Base::ClearChangesMask(PositionLocalSpace); + Base::ClearChangesMask(RotationLocalSpace); + Base::ClearChangesMask(ScaleLocalSpace); + Base::ClearChangesMask(AttachmentFlags); + _changesMask.ResetAll(); + } + + void MirroredPositionData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + PositionData->WriteCreate(data, receiver, owner); + } + + void MirroredPositionData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void MirroredPositionData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + PositionData->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + + void MirroredPositionData::ClearChangesMask() + { + Base::ClearChangesMask(PositionData); + _changesMask.ResetAll(); + } + + void PlayerMirrorHouse::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << Guid; + data << NeighborhoodGUID; + data << uint32(Level); + data << uint32(Favor); + data << uint32(InitiativeFavor); + data << int32(InitiativeCycleID); + data << int32(MapID); + data << int32(PlotID); + } + + void PlayerMirrorHouse::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << Guid; + data << NeighborhoodGUID; + data << uint32(Level); + data << uint32(Favor); + data << uint32(InitiativeFavor); + data << int32(InitiativeCycleID); + data << int32(MapID); + data << int32(PlotID); + } + + bool PlayerMirrorHouse::operator==(PlayerMirrorHouse const& right) const + { + return Guid == right.Guid + && NeighborhoodGUID == right.NeighborhoodGUID + && Level == right.Level + && Favor == right.Favor + && InitiativeFavor == right.InitiativeFavor + && InitiativeCycleID == right.InitiativeCycleID + && MapID == right.MapID + && PlotID == right.PlotID; + } + + void NeighborhoodCharterSignature::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << Guid; + } + + void NeighborhoodCharterSignature::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << Guid; + } + + bool NeighborhoodCharterSignature::operator==(NeighborhoodCharterSignature const& right) const + { + return Guid == right.Guid; + } + + void NeighborhoodCharter::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << int32(Field_4); + data << uint32(Signatures.size()); + for (uint32 i = 0; i < Signatures.size(); ++i) + { + Signatures[i].WriteCreate(data, receiver, owner); + } + data.WriteBits(Name.size() + 1, 8); + data << WorldPackets::SizedCString::Data(Name); + } + + void NeighborhoodCharter::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(Field_0); + data << int32(Field_4); + data << uint32(Signatures.size()); + for (uint32 i = 0; i < Signatures.size(); ++i) + { + Signatures[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + data.FlushBits(); + data.WriteBits(Name.size() + 1, 8); + data << WorldPackets::SizedCString::Data(Name); + } + + bool NeighborhoodCharter::operator==(NeighborhoodCharter const& right) const + { + return Signatures == right.Signatures + && Field_0 == right.Field_0 + && Field_4 == right.Field_4 + && Name == right.Name; + } + + void NeighborhoodOwnershipTransfer::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << NeighborhoodGUID; + data << CurrentOwnerGUID; + data.WriteBits(NeighborhoodName.size() + 1, 8); + data.FlushBits(); + data << WorldPackets::SizedCString::Data(NeighborhoodName); + } + + void NeighborhoodOwnershipTransfer::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << NeighborhoodGUID; + data << CurrentOwnerGUID; + data.WriteBits(NeighborhoodName.size() + 1, 8); + data.FlushBits(); + data << WorldPackets::SizedCString::Data(NeighborhoodName); + } + + bool NeighborhoodOwnershipTransfer::operator==(NeighborhoodOwnershipTransfer const& right) const + { + return NeighborhoodGUID == right.NeighborhoodGUID + && CurrentOwnerGUID == right.CurrentOwnerGUID + && NeighborhoodName == right.NeighborhoodName; + } + + void PlayerHouseInfoComponentData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(Field_8.size()); + } + data << uint32(Houses.size()); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(Field_88.size()); + data << uint32(Field_C0.size()); + data << uint32(Field_F8.size()); + data << uint8(EditorMode); + for (uint32 i = 0; i < Field_8.size(); ++i) + { + data << Field_8[i]; + } + } + for (uint32 i = 0; i < Houses.size(); ++i) + { + Houses[i].WriteCreate(data, receiver, owner); + } + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + for (uint32 i = 0; i < Field_88.size(); ++i) + { + data << Field_88[i]; + } + for (uint32 i = 0; i < Field_C0.size(); ++i) + { + data << Field_C0[i]; + } + for (uint32 i = 0; i < Field_F8.size(); ++i) + { + data << Field_F8[i]; + } + Charter->WriteCreate(data, receiver, owner); + NeighborhoodOwnershipTransfer->WriteCreate(data, receiver, owner); + } + } + + static constexpr void PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(PlayerHouseInfoComponentData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array{ 0x000001FAu }; + } + + void PlayerHouseInfoComponentData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + } + + void PlayerHouseInfoComponentData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) + { + Mask allowedMaskForTarget({ 0x00000005u }); + PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; + } + + void PlayerHouseInfoComponentData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask allowedMaskForTarget({ 0x00000005u }); + PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); + } + + void PlayerHouseInfoComponentData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 9); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreNestedChangesMask) + Field_8.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Field_8.size(), data); + } + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + Houses.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Houses.size(), data); + } + if (changesMask[3]) + { + if (!ignoreNestedChangesMask) + Field_88.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Field_88.size(), data); + } + if (changesMask[4]) + { + if (!ignoreNestedChangesMask) + Field_C0.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Field_C0.size(), data); + } + if (changesMask[5]) + { + if (!ignoreNestedChangesMask) + Field_F8.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Field_F8.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Field_8.size(); ++i) + { + if (Field_8.HasChanged(i) || ignoreNestedChangesMask) + { + data << Field_8[i]; + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < Houses.size(); ++i) + { + if (Houses.HasChanged(i) || ignoreNestedChangesMask) + { + Houses[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[3]) + { + for (uint32 i = 0; i < Field_88.size(); ++i) + { + if (Field_88.HasChanged(i) || ignoreNestedChangesMask) + { + data << Field_88[i]; + } + } + } + if (changesMask[4]) + { + for (uint32 i = 0; i < Field_C0.size(); ++i) + { + if (Field_C0.HasChanged(i) || ignoreNestedChangesMask) + { + data << Field_C0[i]; + } + } + } + if (changesMask[5]) + { + for (uint32 i = 0; i < Field_F8.size(); ++i) + { + if (Field_F8.HasChanged(i) || ignoreNestedChangesMask) + { + data << Field_F8[i]; + } + } + } + if (changesMask[7]) + { + data << uint8(EditorMode); + } + if (changesMask[6]) + { + Charter->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[8]) + { + NeighborhoodOwnershipTransfer->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + + void PlayerHouseInfoComponentData::ClearChangesMask() + { + Base::ClearChangesMask(Field_8); + Base::ClearChangesMask(Houses); + Base::ClearChangesMask(Field_88); + Base::ClearChangesMask(Field_C0); + Base::ClearChangesMask(Field_F8); + Base::ClearChangesMask(Charter); + Base::ClearChangesMask(EditorMode); + Base::ClearChangesMask(NeighborhoodOwnershipTransfer); + _changesMask.ResetAll(); + } + + void HousingStorageData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + WriteMapFieldCreate(Decor, data, receiver, owner); + data << uint32(DecorMaxOwnedCount); + } + + void HousingStorageData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingStorageData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, BaseEntity const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + WriteMapFieldUpdate(Decor, ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[2]) + { + data << uint32(DecorMaxOwnedCount); + } + } + } + + void HousingStorageData::ClearChangesMask() + { + Base::ClearChangesMask(Decor); + Base::ClearChangesMask(DecorMaxOwnedCount); + _changesMask.ResetAll(); + } + + void HousingFixtureData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + data << int32(ExteriorComponentID); + data << int32(HouseExteriorWmoDataID); + data << int32(ExteriorComponentHookID); + data << *HouseGUID; + data << *AttachParentGUID; + data << *Guid; + data << *GameObjectGUID; + data << uint8(ExteriorComponentType); + data << uint8(Field_59); + data << uint8(Size); + } + + void HousingFixtureData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Object const* owner) const + { + WriteUpdate(_changesMask, data, receiver, owner, false); + } + + void HousingFixtureData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Object const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 11); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << int32(ExteriorComponentID); + } + if (changesMask[2]) + { + data << int32(HouseExteriorWmoDataID); + } + if (changesMask[3]) + { + data << int32(ExteriorComponentHookID); + } + if (changesMask[4]) + { + data << *HouseGUID; + } + if (changesMask[5]) + { + data << *AttachParentGUID; + } + if (changesMask[6]) + { + data << *Guid; + } + if (changesMask[7]) + { + data << *GameObjectGUID; + } + if (changesMask[8]) + { + data << uint8(ExteriorComponentType); + } + if (changesMask[9]) + { + data << uint8(Field_59); + } + if (changesMask[10]) + { + data << uint8(Size); + } + } + } + + void HousingFixtureData::ClearChangesMask() + { + Base::ClearChangesMask(ExteriorComponentID); + Base::ClearChangesMask(HouseExteriorWmoDataID); + Base::ClearChangesMask(ExteriorComponentHookID); + Base::ClearChangesMask(HouseGUID); + Base::ClearChangesMask(AttachParentGUID); + Base::ClearChangesMask(Guid); + Base::ClearChangesMask(GameObjectGUID); + Base::ClearChangesMask(ExteriorComponentType); + Base::ClearChangesMask(Field_59); + Base::ClearChangesMask(Size); + _changesMask.ResetAll(); + } + + void PlayerInitiativeInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int64(RemainingDuration); + data << int32(CurrentInitiativeID); + data << int32(CurrentMilestoneID); + data << int32(CurrentCycleID); + data << float(ProgressRequired); + data << float(CurrentProgress); + data << float(PlayerTotalContribution); + } + + void PlayerInitiativeInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + data.FlushBits(); + if (changesMask[0]) + { + data << int64(RemainingDuration); + } + if (changesMask[1]) + { + data << int32(CurrentInitiativeID); + } + if (changesMask[2]) + { + data << int32(CurrentMilestoneID); + } + if (changesMask[3]) + { + data << int32(CurrentCycleID); } if (changesMask[4]) { - InitiativeInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + data << float(ProgressRequired); } if (changesMask[5]) { - WriteSetFieldUpdate(Houses, ignoreNestedChangesMask, data, receiver, owner); + data << float(CurrentProgress); + } + if (changesMask[6]) + { + data << float(PlayerTotalContribution); } } -} -void PlayerInitiativeComponentData::ClearChangesMask() -{ - Base::ClearChangesMask(CompletedTasks); - Base::ClearChangesMask(CompletedInitiatives); - Base::ClearChangesMask(NeighborhoodGUID); - Base::ClearChangesMask(InitiativeInfo); - Base::ClearChangesMask(Houses); - _changesMask.ResetAll(); -} + void PlayerInitiativeInfo::ClearChangesMask() + { + Base::ClearChangesMask(RemainingDuration); + Base::ClearChangesMask(CurrentInitiativeID); + Base::ClearChangesMask(CurrentMilestoneID); + Base::ClearChangesMask(CurrentCycleID); + Base::ClearChangesMask(ProgressRequired); + Base::ClearChangesMask(CurrentProgress); + Base::ClearChangesMask(PlayerTotalContribution); + _changesMask.ResetAll(); + } + + void PlayerInitiativeTaskInfo::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int32(TaskID); + data << int32(TimesCompleted); + } + + void PlayerInitiativeTaskInfo::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) + { + data << int32(TaskID); + } + if (changesMask[1]) + { + data << int32(TimesCompleted); + } + } + + void PlayerInitiativeTaskInfo::ClearChangesMask() + { + Base::ClearChangesMask(TaskID); + Base::ClearChangesMask(TimesCompleted); + _changesMask.ResetAll(); + } + + void NICompletedMilestoneEntry::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int64(AwardDate); + data << uint32(MilestoneID); + } + + void NICompletedMilestoneEntry::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << int64(AwardDate); + data << uint32(MilestoneID); + } + + bool NICompletedMilestoneEntry::operator==(NICompletedMilestoneEntry const& right) const + { + return AwardDate == right.AwardDate + && MilestoneID == right.MilestoneID; + } + + void NICompletedInitiativesEntry::WriteCreate(ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(InitiativeID); + data << uint32(CompletedMilestones.size()); + for (uint32 i = 0; i < CompletedMilestones.size(); ++i) + { + CompletedMilestones[i].WriteCreate(data, receiver, owner); + } + data.WriteBit(Completed); + data.FlushBits(); + } + + void NICompletedInitiativesEntry::WriteUpdate(bool ignoreChangesMask, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << uint32(InitiativeID); + data << uint32(CompletedMilestones.size()); + for (uint32 i = 0; i < CompletedMilestones.size(); ++i) + { + CompletedMilestones[i].WriteUpdate(ignoreChangesMask, data, receiver, owner); + } + data.FlushBits(); + data.FlushBits(); + data.WriteBit(Completed); + data.FlushBits(); + } + + bool NICompletedInitiativesEntry::operator==(NICompletedInitiativesEntry const& right) const + { + return Completed == right.Completed + && CompletedMilestones == right.CompletedMilestones + && InitiativeID == right.InitiativeID; + } + + void PlayerInitiativeComponentData::WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + data << *NeighborhoodGUID; + InitiativeInfo->WriteCreate(data, receiver, owner); + data << uint32(CompletedTasks.size()); + data << uint32(CompletedInitiatives.size()); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + WriteSetFieldCreate(Houses, data, receiver, owner); + } + for (uint32 i = 0; i < CompletedTasks.size(); ++i) + { + CompletedTasks[i].WriteCreate(data, receiver, owner); + } + for (uint32 i = 0; i < CompletedInitiatives.size(); ++i) + { + CompletedInitiatives[i].WriteCreate(data, receiver, owner); + } + } + + static constexpr void PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(PlayerInitiativeComponentData::Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array{ 0x00000020u }; + } + + void PlayerInitiativeComponentData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) + { + PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + } + + void PlayerInitiativeComponentData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) + { + Mask allowedMaskForTarget({ 0x0000001Fu }); + PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; + } + + void PlayerInitiativeComponentData::WriteUpdate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, Player const* owner) const + { + Mask allowedMaskForTarget({ 0x0000001Fu }); + PlayerInitiativeComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(_changesMask & allowedMaskForTarget, data, receiver, owner, false); + } + + void PlayerInitiativeComponentData::WriteUpdate(Mask const& changesMask, ByteBuffer& data, Player const* receiver, Player const* owner, bool ignoreNestedChangesMask) const + { + data.WriteBits(changesMask.GetBlock(0), 6); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreNestedChangesMask) + CompletedTasks.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CompletedTasks.size(), data); + } + if (changesMask[2]) + { + if (!ignoreNestedChangesMask) + CompletedInitiatives.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CompletedInitiatives.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < CompletedTasks.size(); ++i) + { + if (CompletedTasks.HasChanged(i) || ignoreNestedChangesMask) + { + CompletedTasks[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < CompletedInitiatives.size(); ++i) + { + if (CompletedInitiatives.HasChanged(i) || ignoreNestedChangesMask) + { + CompletedInitiatives[i].WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + } + } + if (changesMask[3]) + { + data << *NeighborhoodGUID; + } + if (changesMask[4]) + { + InitiativeInfo->WriteUpdate(ignoreNestedChangesMask, data, receiver, owner); + } + if (changesMask[5]) + { + WriteSetFieldUpdate(Houses, ignoreNestedChangesMask, data, receiver, owner); + } + } + } + + void PlayerInitiativeComponentData::ClearChangesMask() + { + Base::ClearChangesMask(CompletedTasks); + Base::ClearChangesMask(CompletedInitiatives); + Base::ClearChangesMask(NeighborhoodGUID); + Base::ClearChangesMask(InitiativeInfo); + Base::ClearChangesMask(Houses); + _changesMask.ResetAll(); + } } diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 9918c70c2..04f17b6c4 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -1946,19 +1946,22 @@ struct HousingRoomComponentMeshData : public IsUpdateFieldStructureTag, public H void ClearChangesMask(); }; -struct HousingPlayerHouseData : public IsUpdateFieldStructureTag, public HasChangesMask<12> +struct HousingPlayerHouseData : public IsUpdateFieldStructureTag, public HasChangesMask<10> { + // IDA-verified wire order: must match client struct layout (72 bytes, 8 internal + 64 wire). + // Client struct offsets: +8=BnetAccount, +24=PlotIndex(def -1), +28=Level(def 1), + // +32=Favor, +40=Interior, +44=Exterior, +48=Room, +52=Fixture, +56=EntityGUID. + // HOUSE_LEVEL_CHANGED event pushes: level, interior, exterior, room, fixture. + // HouseType and HouseSize do NOT exist in this fragment. UpdateField BnetAccount; - UpdateField HouseType; - UpdateField HouseSize; - UpdateField PlotIndex; - UpdateField Level; - UpdateField Favor; - UpdateField InteriorDecorPlacementBudget; - UpdateField ExteriorDecorPlacementBudget; - UpdateField ExteriorFixtureBudget; - UpdateField RoomPlacementBudget; - UpdateField EntityGUID; + UpdateField PlotIndex; + UpdateField Level; + UpdateField Favor; + UpdateField InteriorDecorPlacementBudget; + UpdateField ExteriorDecorPlacementBudget; + UpdateField RoomPlacementBudget; + UpdateField ExteriorFixtureBudget; + UpdateField EntityGUID; using OwnerObject = BaseEntity; void WriteCreate(EnumFlag fieldVisibilityFlags, ByteBuffer& data, Player const* receiver, BaseEntity const* owner) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bc67d066e..e51d676e9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -19018,12 +19018,31 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol NeighborhoodInitiativeEntry const* initEntry = sNeighborhoodInitiativeStore.LookupEntry(activeInit->InitiativeID); uint32 cycleID = sInitiativeManager.GetActiveCycleForInitiative(activeInit->InitiativeID); - // Calculate remaining duration from start time + DB2 duration - int64 remainingDuration = 0; + // Calculate remaining duration from start time + DB2 duration. + // Check both NeighborhoodInitiative.Duration and InitiativeCycle.Duration. + // If neither provides a duration, use a 7-day default so the client shows + // the endeavor as active rather than expired (Duration=0 ? hidden). + // Duration from DB2 is in days ? convert to seconds. + // Sniff-verified: RemainingDuration is in seconds (sniff value 972957 ? 11.25 days). + int64 durationSec = 0; if (initEntry && initEntry->Duration > 0) + durationSec = static_cast(initEntry->Duration) * 86400; + else if (cycleID) { - int64 elapsed = static_cast(GameTime::GetGameTime()) - static_cast(activeInit->StartTime); - remainingDuration = std::max(0, static_cast(initEntry->Duration) - elapsed); + InitiativeCycleEntry const* cycleEntry = sInitiativeCycleStore.LookupEntry(cycleID); + if (cycleEntry && cycleEntry->Duration > 0) + durationSec = static_cast(cycleEntry->Duration) * 86400; + } + if (durationSec <= 0) + durationSec = 7 * DAY; // 7-day fallback + + int64 elapsed = static_cast(GameTime::GetGameTime()) - static_cast(activeInit->StartTime); + int64 remainingDuration = durationSec - elapsed; + // If expired, reset start time so the initiative stays active + if (remainingDuration <= 0) + { + activeInit->StartTime = static_cast(GameTime::GetGameTime()); + remainingDuration = durationSec; } // Calculate progress in the 0-1000 scale (sniff: ProgressRequired=1000) @@ -19082,6 +19101,75 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol } } + // Pre-populate Housing/4 (NeighborhoodMirrorEntity) and Housing/3 (HousingPlayerHouseEntity) + // BEFORE BuildCreateUpdateBlockForPlayer runs. The CREATE block must include the full Houses + // array so the client sees occupied plots at the correct indices. If we only populate these + // during SendInitialPacketsAfterAddToMap (after CREATE), the client receives an empty Houses + // array in CREATE and a DynamicUpdateField UPDATE that grows the array ? causing it to map + // houses to indices 0,1,2 instead of their real PlotIndex values (e.g. 7,9,47,51). + if (GetSession() && !_housings.empty() && _housings[0] && !_housings[0]->GetNeighborhoodGuid().IsEmpty()) + { + Neighborhood const* neighborhood = sNeighborhoodMgr.GetNeighborhood(_housings[0]->GetNeighborhoodGuid()); + if (neighborhood) + { + // --- Housing/4: NeighborhoodMirrorEntity --- + // The entity GUID must match the neighborhood's actual GUID so the client + // can associate it with NeighborhoodGUID references in JamCliHouse packets. + // WorldSession creates it with battlenetAccountId as placeholder; fix it here. + HousingNeighborhoodMirrorEntity& mirrorEntity = GetSession()->GetHousingNeighborhoodMirrorEntity(); + mirrorEntity.ResetGuid(neighborhood->GetGuid()); + mirrorEntity.SetName(neighborhood->GetName()); + mirrorEntity.SetOwnerGUID(neighborhood->GetOwnerGuid()); + + // Add ALL 55 plot entries so Houses[i] = PlotIndex i + mirrorEntity.ClearHouses(); + for (auto const& plot : neighborhood->GetPlots()) + { + if (plot.IsOccupied() && !plot.HouseGuid.IsEmpty()) + mirrorEntity.AddHouse(plot.HouseGuid, plot.OwnerGuid); + else + mirrorEntity.AddHouse(ObjectGuid::Empty, ObjectGuid::Empty); + } + + // Add managers + mirrorEntity.ClearManagers(); + for (auto const& member : neighborhood->GetMembers()) + { + if (member.Role == NEIGHBORHOOD_ROLE_MANAGER || member.Role == NEIGHBORHOOD_ROLE_OWNER) + { + ObjectGuid bnetGuid; + if (Player* managerPlayer = ObjectAccessor::FindPlayer(member.PlayerGuid)) + bnetGuid = managerPlayer->GetSession()->GetBattlenetAccountGUID(); + mirrorEntity.AddManager(bnetGuid, member.PlayerGuid); + } + } + + TC_LOG_DEBUG("housing", "Player::LoadFromDB: Pre-populated Housing/4 mirror entity with {} plots from neighborhood {}", + MAX_NEIGHBORHOOD_PLOTS, neighborhood->GetName()); + + // --- Housing/3: HousingPlayerHouseEntity --- + Housing* housing = _housings[0].get(); + if (housing && !housing->GetHouseGuid().IsEmpty()) + { + HousingPlayerHouseEntity& houseEntity = GetSession()->GetHousingPlayerHouseEntity(); + houseEntity.SetBnetAccount(GetSession()->GetBattlenetAccountGUID()); + houseEntity.SetEntityGUID(housing->GetHouseGuid()); + houseEntity.SetPlotIndex(static_cast(housing->GetPlotIndex())); + houseEntity.SetLevel(housing->GetLevel()); + houseEntity.SetFavor(housing->GetFavor64()); + houseEntity.SetBudgets( + housing->GetMaxInteriorDecorBudget(), + housing->GetMaxExteriorDecorBudget(), + housing->GetMaxRoomBudget(), + housing->GetMaxFixtureBudget() + ); + + TC_LOG_DEBUG("housing", "Player::LoadFromDB: Pre-populated Housing/3 house entity: Plot={} Level={} HouseGuid={}", + housing->GetPlotIndex(), housing->GetLevel(), housing->GetHouseGuid().ToString()); + } + } + } + //WowCommunity _InitHonorLevelOnLoadFromDB(fields.honor, fields.honorLevel); @@ -25742,8 +25830,6 @@ void Player::SendInitialPacketsAfterAddToMap() HousingPlayerHouseEntity& houseEntity = GetSession()->GetHousingPlayerHouseEntity(); houseEntity.SetBnetAccount(GetSession()->GetBattlenetAccountGUID()); houseEntity.SetEntityGUID(housing->GetHouseGuid()); - houseEntity.SetHouseType(housing->GetHouseType()); - houseEntity.SetHouseSize(static_cast(housing->GetHouseSize())); houseEntity.SetPlotIndex(static_cast(housing->GetPlotIndex())); houseEntity.SetLevel(housing->GetLevel()); houseEntity.SetFavor(housing->GetFavor64()); diff --git a/src/server/game/Handlers/HousingHandler.cpp b/src/server/game/Handlers/HousingHandler.cpp index 331a0c744..d64df26ff 100644 --- a/src/server/game/Handlers/HousingHandler.cpp +++ b/src/server/game/Handlers/HousingHandler.cpp @@ -551,10 +551,11 @@ void WorldSession::HandleHousingDecorSetEditMode(WorldPackets::Housing::HousingD updateData.BuildPacket(&updatePacket); player->SendDirectMessage(&updatePacket); - // Clear change masks after manual send to prevent duplicate sends on next map tick + // Clear change masks AND remove from _updateObjects to prevent duplicate + // VALUES_UPDATE on next map tick (causes "Object update failed" on client). player->ClearUpdateMask(false); - GetBattlenetAccount().ClearUpdateMask(false); - GetHousingPlayerHouseEntity().ClearUpdateMask(false); + GetBattlenetAccount().ClearUpdateMask(true); + GetHousingPlayerHouseEntity().ClearUpdateMask(true); } // Diagnostic: log placed decor GUIDs from Housing vs what's on spawned MeshObjects. @@ -1053,8 +1054,8 @@ void WorldSession::HandleHousingDecorRequestStorage(WorldPackets::Housing::Housi updateData.BuildPacket(&updatePacket); player->SendDirectMessage(&updatePacket); - GetBattlenetAccount().ClearUpdateMask(false); - GetHousingPlayerHouseEntity().ClearUpdateMask(false); + GetBattlenetAccount().ClearUpdateMask(true); + GetHousingPlayerHouseEntity().ClearUpdateMask(true); } // 3. Send GET_PLAYER_HOUSES_INFO_RESPONSE @@ -1215,6 +1216,47 @@ void WorldSession::HandleHousingFixtureSetEditMode(WorldPackets::Housing::Housin response.Result = static_cast(HOUSING_RESULT_SUCCESS); SendPacket(response.Write()); + // Sync entity data so the client receives budget values when switching to customize mode. + // Without this, the client sees 0/0 budgets because the Player entity's EditorMode changed + // but the HousingPlayerHouseEntity/Account entity data was never flushed. + if (housingFixtureSetEditMode.Active) + { + housing->ResetStoragePopulated(); + housing->PopulateCatalogStorageEntries(); + housing->SyncUpdateFields(); + + player->BuildUpdateChangesMask(); + GetBattlenetAccount().BuildUpdateChangesMask(); + GetHousingPlayerHouseEntity().BuildUpdateChangesMask(); + + UpdateData updateData(player->GetMapId()); + WorldPacket updatePacket; + player->BuildValuesUpdateBlockForPlayer(&updateData, player); + + if (player->HaveAtClient(&GetBattlenetAccount())) + GetBattlenetAccount().BuildValuesUpdateBlockForPlayer(&updateData, player); + else + { + GetBattlenetAccount().BuildCreateUpdateBlockForPlayer(&updateData, player); + player->m_clientGUIDs.insert(GetBattlenetAccount().GetGUID()); + } + + if (player->HaveAtClient(&GetHousingPlayerHouseEntity())) + GetHousingPlayerHouseEntity().BuildValuesUpdateBlockForPlayer(&updateData, player); + else + { + GetHousingPlayerHouseEntity().BuildCreateUpdateBlockForPlayer(&updateData, player); + player->m_clientGUIDs.insert(GetHousingPlayerHouseEntity().GetGUID()); + } + + updateData.BuildPacket(&updatePacket); + player->SendDirectMessage(&updatePacket); + + player->ClearUpdateMask(false); + GetBattlenetAccount().ClearUpdateMask(true); + GetHousingPlayerHouseEntity().ClearUpdateMask(true); + } + TC_LOG_INFO("housing", "CMSG_HOUSING_FIXTURE_SET_EDITOR_MODE_ACTIVE Active: {}", housingFixtureSetEditMode.Active); } @@ -1576,6 +1618,45 @@ void WorldSession::HandleHousingRoomSetLayoutEditMode(WorldPackets::Housing::Hou response.Active = housingRoomSetLayoutEditMode.Active; SendPacket(response.Write()); + // Sync entity data so the client receives budget values when switching to layout mode. + if (housingRoomSetLayoutEditMode.Active) + { + housing->ResetStoragePopulated(); + housing->PopulateCatalogStorageEntries(); + housing->SyncUpdateFields(); + + player->BuildUpdateChangesMask(); + GetBattlenetAccount().BuildUpdateChangesMask(); + GetHousingPlayerHouseEntity().BuildUpdateChangesMask(); + + UpdateData updateData(player->GetMapId()); + WorldPacket updatePacket; + player->BuildValuesUpdateBlockForPlayer(&updateData, player); + + if (player->HaveAtClient(&GetBattlenetAccount())) + GetBattlenetAccount().BuildValuesUpdateBlockForPlayer(&updateData, player); + else + { + GetBattlenetAccount().BuildCreateUpdateBlockForPlayer(&updateData, player); + player->m_clientGUIDs.insert(GetBattlenetAccount().GetGUID()); + } + + if (player->HaveAtClient(&GetHousingPlayerHouseEntity())) + GetHousingPlayerHouseEntity().BuildValuesUpdateBlockForPlayer(&updateData, player); + else + { + GetHousingPlayerHouseEntity().BuildCreateUpdateBlockForPlayer(&updateData, player); + player->m_clientGUIDs.insert(GetHousingPlayerHouseEntity().GetGUID()); + } + + updateData.BuildPacket(&updatePacket); + player->SendDirectMessage(&updatePacket); + + player->ClearUpdateMask(false); + GetBattlenetAccount().ClearUpdateMask(true); + GetHousingPlayerHouseEntity().ClearUpdateMask(true); + } + TC_LOG_INFO("housing", "CMSG_HOUSING_ROOM_SET_EDITOR_MODE_ACTIVE Active: {}", housingRoomSetLayoutEditMode.Active); } diff --git a/src/server/game/Handlers/NeighborhoodHandler.cpp b/src/server/game/Handlers/NeighborhoodHandler.cpp index b48dee4b8..4bf6e0858 100644 --- a/src/server/game/Handlers/NeighborhoodHandler.cpp +++ b/src/server/game/Handlers/NeighborhoodHandler.cpp @@ -377,7 +377,7 @@ void WorldSession::HandleNeighborhoodCharterAddSignature(WorldPackets::Neighborh if (!charter.AddSignature(player->GetGUID())) { WorldPackets::Neighborhood::NeighborhoodCharterAddSignatureResponse response; - response.Result = static_cast(HOUSING_RESULT_GENERIC_FAILURE); + response.Result = static_cast(HOUSING_RESULT_DUPLICATE_CHARTER_SIGNATURE); SendPacket(response.Write()); TC_LOG_DEBUG("housing", "HandleNeighborhoodCharterAddSignature: Player {} could not sign charter {}", @@ -1058,7 +1058,7 @@ void WorldSession::HandleNeighborhoodBuyHouse(WorldPackets::Neighborhood::Neighb if (!player->HasEnoughMoney(HOUSE_PURCHASE_COST_COPPER)) { WorldPackets::Neighborhood::NeighborhoodBuyHouseResponse response; - response.Result = static_cast(HOUSING_RESULT_GENERIC_FAILURE); + response.Result = static_cast(HOUSING_RESULT_CANNOT_AFFORD); SendPacket(response.Write()); TC_LOG_DEBUG("housing", "HandleNeighborhoodBuyHouse: Player {} cannot afford house (need {} copper, has {})", @@ -1318,8 +1318,8 @@ void WorldSession::HandleNeighborhoodBuyHouse(WorldPackets::Neighborhood::Neighb updateData.BuildPacket(&updatePacket); player->SendDirectMessage(&updatePacket); - GetBattlenetAccount().ClearUpdateMask(false); - GetHousingPlayerHouseEntity().ClearUpdateMask(false); + GetBattlenetAccount().ClearUpdateMask(true); + GetHousingPlayerHouseEntity().ClearUpdateMask(true); } TC_LOG_ERROR("housing", "HandleNeighborhoodBuyHouse: Sent proactive STORAGE_RSP + Account + HouseEntity update (CatalogEntries={})", @@ -1396,7 +1396,7 @@ void WorldSession::HandleNeighborhoodMoveHouse(WorldPackets::Neighborhood::Neigh if (!player->HasEnoughMoney(HOUSE_MOVE_COST_COPPER)) { WorldPackets::Neighborhood::NeighborhoodMoveHouseResponse response; - response.Result = static_cast(HOUSING_RESULT_GENERIC_FAILURE); + response.Result = static_cast(HOUSING_RESULT_CANNOT_AFFORD); SendPacket(response.Write()); TC_LOG_DEBUG("housing", "HandleNeighborhoodMoveHouse: Player {} cannot afford move (need {} copper, has {})", @@ -1710,7 +1710,7 @@ void WorldSession::HandleNeighborhoodGetRoster(WorldPackets::Neighborhood::Neigh if (!neighborhood->IsMember(player->GetGUID())) { WorldPackets::Neighborhood::NeighborhoodGetRosterResponse response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); + response.Result = static_cast(HOUSING_RESULT_PERMISSION_DENIED); SendPacket(response.Write()); TC_LOG_DEBUG("housing", "HandleNeighborhoodGetRoster: Player {} is not a member of neighborhood {}", @@ -1913,7 +1913,23 @@ void WorldSession::HandleNeighborhoodInitiativeServiceStatusCheck(WorldPackets:: TC_LOG_DEBUG("housing", "CMSG_NEIGHBORHOOD_INITIATIVE_SERVICE_STATUS_CHECK for player {}", player->GetGUID().ToString()); + // Send initiative service status sInitiativeManager.SendInitiativeServiceStatus(this, true); + + // Proactively send initiative data ? the client's C_NeighborhoodInitiative singleton + // requires SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT to set its isLoaded flag. + // Without this, GetNeighborhoodInitiativeInfo() returns nil and the endeavor UI is empty. + // Sniff-verified: the live server sends this SMSG proactively (not only in response to + // CMSG_INITIATIVE_UPDATE_ACTIVE_NEIGHBORHOOD which the client rarely/never sends). + if (Housing* housing = player->GetHousing()) + { + ObjectGuid nhObjGuid = housing->GetNeighborhoodGuid(); + if (!nhObjGuid.IsEmpty()) + { + uint64 nhGuid = nhObjGuid.GetCounter(); + sInitiativeManager.SendPlayerInitiativeInfo(this, nhObjGuid, nhGuid); + } + } } void WorldSession::HandleGetAvailableInitiativeRequest(WorldPackets::Neighborhood::GetAvailableInitiativeRequest const& getAvailableInitiativeRequest) @@ -1926,13 +1942,14 @@ void WorldSession::HandleGetAvailableInitiativeRequest(WorldPackets::Neighborhoo if (!neighborhood) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); + response.HasError = true; SendPacket(response.Write()); return; } - uint64 nhGuid = neighborhood->GetGuid().GetCounter(); - sInitiativeManager.SendPlayerInitiativeInfo(this, nhGuid); + ObjectGuid nhObjGuid = neighborhood->GetGuid(); + uint64 nhGuid = nhObjGuid.GetCounter(); + sInitiativeManager.SendPlayerInitiativeInfo(this, nhObjGuid, nhGuid); TC_LOG_DEBUG("housing", "CMSG_GET_AVAILABLE_INITIATIVE_REQUEST NeighborhoodGuid: {}, Player: {}", getAvailableInitiativeRequest.NeighborhoodGuid.ToString(), player->GetGUID().ToString()); @@ -1977,13 +1994,14 @@ void WorldSession::HandleInitiativeUpdateActiveNeighborhood(WorldPackets::Neighb return; } - uint64 nhGuid = neighborhood->GetGuid().GetCounter(); + ObjectGuid nhObjGuid = neighborhood->GetGuid(); + uint64 nhGuid = nhObjGuid.GetCounter(); // Send initiative service status to confirm the service is active sInitiativeManager.SendInitiativeServiceStatus(this, true); // Send current initiative info for the active neighborhood (with real task progress) - sInitiativeManager.SendPlayerInitiativeInfo(this, nhGuid); + sInitiativeManager.SendPlayerInitiativeInfo(this, nhObjGuid, nhGuid); TC_LOG_DEBUG("housing", "SMSG_INITIATIVE_SERVICE_STATUS + SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT sent for NeighborhoodGuid: {}", initiativeUpdateActiveNeighborhood.NeighborhoodGuid.ToString()); @@ -2034,19 +2052,11 @@ void WorldSession::HandleInitiativeReportProgress(WorldPackets::Neighborhood::In TC_LOG_DEBUG("housing", "CMSG_INITIATIVE_REPORT_PROGRESS NeighborhoodGuid: {} Player: {}", packet.NeighborhoodGuid.ToString(), player->GetGUID().ToString()); - Neighborhood* neighborhood = sNeighborhoodMgr.ResolveNeighborhood(packet.NeighborhoodGuid, player); - if (!neighborhood) - { - WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); - SendPacket(response.Write()); - return; - } - - uint64 nhGuid = neighborhood->GetGuid().GetCounter(); - - // Client is requesting initiative info for this neighborhood ? send current state - sInitiativeManager.SendPlayerInitiativeInfo(this, nhGuid); + // This is a client-side progress report (e.g. criteria completion tick), NOT a + // request for initiative info. Responding with SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT + // caused the client to re-report in an infinite loop, stalling the UI. + // The initiative data is already delivered via the PlayerInitiativeComponent_C + // fragment (Fragment 37) in the player's UPDATE_OBJECT at login. } void WorldSession::HandleGetInitiativeClaimRewardRequest(WorldPackets::Neighborhood::GetInitiativeClaimRewardRequest const& packet) @@ -2102,7 +2112,7 @@ void WorldSession::HandleGetInitiativeLeaderboardRequest(WorldPackets::Neighborh if (!neighborhood) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); + response.HasError = true; SendPacket(response.Write()); return; } @@ -2177,19 +2187,20 @@ void WorldSession::HandleGetInitiativeTaskAcceptRequest(WorldPackets::Neighborho if (!neighborhood) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); + response.HasError = true; SendPacket(response.Write()); return; } - uint64 nhGuid = neighborhood->GetGuid().GetCounter(); + ObjectGuid nhObjGuid = neighborhood->GetGuid(); + uint64 nhGuid = nhObjGuid.GetCounter(); // Verify the task exists in the active initiative ActiveInitiative* active = sInitiativeManager.GetActiveInitiative(nhGuid); if (!active) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_GENERIC_FAILURE); + response.HasError = true; SendPacket(response.Write()); return; } @@ -2198,7 +2209,7 @@ void WorldSession::HandleGetInitiativeTaskAcceptRequest(WorldPackets::Neighborho if (taskItr == active->TaskProgress.end()) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_GENERIC_FAILURE); + response.HasError = true; SendPacket(response.Write()); return; } @@ -2208,7 +2219,7 @@ void WorldSession::HandleGetInitiativeTaskAcceptRequest(WorldPackets::Neighborho taskItr->second.Status = INITIATIVE_TASK_STATUS_IN_PROGRESS; // Send updated initiative info - sInitiativeManager.SendPlayerInitiativeInfo(this, nhGuid); + sInitiativeManager.SendPlayerInitiativeInfo(this, nhObjGuid, nhGuid); } void WorldSession::HandleGetInitiativeTaskAbandonRequest(WorldPackets::Neighborhood::GetInitiativeTaskAbandonRequest const& packet) @@ -2224,17 +2235,18 @@ void WorldSession::HandleGetInitiativeTaskAbandonRequest(WorldPackets::Neighborh if (!neighborhood) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); + response.HasError = true; SendPacket(response.Write()); return; } - uint64 nhGuid = neighborhood->GetGuid().GetCounter(); + ObjectGuid nhObjGuid = neighborhood->GetGuid(); + uint64 nhGuid = nhObjGuid.GetCounter(); ActiveInitiative* active = sInitiativeManager.GetActiveInitiative(nhGuid); if (!active) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_GENERIC_FAILURE); + response.HasError = true; SendPacket(response.Write()); return; } @@ -2249,7 +2261,7 @@ void WorldSession::HandleGetInitiativeTaskAbandonRequest(WorldPackets::Neighborh SendPacket(clearPacket.Write()); // Send updated initiative info - sInitiativeManager.SendPlayerInitiativeInfo(this, nhGuid); + sInitiativeManager.SendPlayerInitiativeInfo(this, nhObjGuid, nhGuid); } void WorldSession::HandleGetInitiativeTaskProgressRequest(WorldPackets::Neighborhood::GetInitiativeTaskProgressRequest const& packet) @@ -2265,15 +2277,16 @@ void WorldSession::HandleGetInitiativeTaskProgressRequest(WorldPackets::Neighbor if (!neighborhood) { WorldPackets::Housing::GetPlayerInitiativeInfoResult response; - response.Result = static_cast(HOUSING_RESULT_NEIGHBORHOOD_NOT_FOUND); + response.HasError = true; SendPacket(response.Write()); return; } - uint64 nhGuid = neighborhood->GetGuid().GetCounter(); + ObjectGuid nhObjGuid = neighborhood->GetGuid(); + uint64 nhGuid = nhObjGuid.GetCounter(); // Send current initiative info which includes all task progress - sInitiativeManager.SendPlayerInitiativeInfo(this, nhGuid); + sInitiativeManager.SendPlayerInitiativeInfo(this, nhObjGuid, nhGuid); } // ============================================================ diff --git a/src/server/game/Housing/Housing.cpp b/src/server/game/Housing/Housing.cpp index c5bc6d609..967ef7571 100644 --- a/src/server/game/Housing/Housing.cpp +++ b/src/server/game/Housing/Housing.cpp @@ -75,8 +75,11 @@ bool Housing::LoadFromDB(PreparedQueryResult housing, PreparedQueryResult decor, return false; Field* fields = housing->Fetch(); - // Expected columns: houseGuid, neighborhoodGuid, plotIndex, level, favor, settingsFlags, exteriorLocked, houseSize, houseType - _houseGuid = ObjectGuid::Create(/*subType*/ 3, /*arg1*/ sRealmList->GetCurrentRealmId().Realm, /*arg2*/ 7, fields[0].GetUInt64()); + // Expected columns: houseId, neighborhoodGuid, plotIndex, level, favor, settingsFlags, exteriorLocked, houseSize, houseType, ... + // fields[0] = houseId (DB2 entry ID) ? NOT used as GUID counter. + // Housing GUID counter must match HousingPlayerHouseEntity GUID (WorldSession.cpp), which uses battlenetAccountId. + uint32 bnetAccountId = _owner->GetSession()->GetBattlenetAccountId(); + _houseGuid = ObjectGuid::Create(/*subType*/ 3, /*arg1*/ sRealmList->GetCurrentRealmId().Realm, /*arg2*/ 7, uint64(bnetAccountId)); _neighborhoodGuid = ObjectGuid::Create(/*subType*/ 4, /*arg1*/ sRealmList->GetCurrentRealmId().Realm, /*arg2*/ 0, fields[1].GetUInt64()); _plotIndex = fields[2].GetUInt8(); _level = fields[3].GetUInt32(); @@ -2037,8 +2040,7 @@ void Housing::SyncUpdateFields() HousingPlayerHouseEntity& houseEntity = _owner->GetSession()->GetHousingPlayerHouseEntity(); houseEntity.SetBnetAccount(_owner->GetSession()->GetBattlenetAccountGUID()); houseEntity.SetEntityGUID(_houseGuid); - houseEntity.SetHouseType(_houseType); - houseEntity.SetHouseSize(static_cast(_houseSize)); + // HouseType and HouseSize are NOT part of this fragment (IDA-verified). houseEntity.SetPlotIndex(static_cast(_plotIndex)); houseEntity.SetLevel(_level); houseEntity.SetFavor(_favor64); @@ -2051,9 +2053,9 @@ void Housing::SyncUpdateFields() GetMaxFixtureBudget() ); - TC_LOG_ERROR("network", "Housing::SyncUpdateFields: EntityGUID={} BnetAccount={} HouseType={} HouseSize={} PlotIndex={} Level={} Favor={} Budgets=[{},{},{},{}]", + TC_LOG_DEBUG("housing", "Housing::SyncUpdateFields: EntityGUID={} BnetAccount={} PlotIndex={} Level={} Favor={} Budgets=[{},{},{},{}]", _houseGuid.ToString(), _owner->GetSession()->GetBattlenetAccountGUID().ToString(), - _houseType, _houseSize, _plotIndex, _level, _favor64, + _plotIndex, _level, _favor64, GetMaxInteriorDecorBudget(), GetMaxExteriorDecorBudget(), GetMaxRoomBudget(), GetMaxFixtureBudget()); } diff --git a/src/server/game/Housing/HousingMap.cpp b/src/server/game/Housing/HousingMap.cpp index 0327f33e7..997d6a933 100644 --- a/src/server/game/Housing/HousingMap.cpp +++ b/src/server/game/Housing/HousingMap.cpp @@ -497,7 +497,7 @@ void HousingMap::SetPlotOwnershipState(uint8 plotIndex, bool owned) uint32 neighborhoodMapId = _neighborhood->GetNeighborhoodMapID(); std::vector plots = sHousingMgr.GetPlotsForMap(neighborhoodMapId); - TC_LOG_ERROR("housing", "SetPlotOwnershipState: Broadcasting WorldState for plot {} " + TC_LOG_DEBUG("housing", "SetPlotOwnershipState: Broadcasting WorldState for plot {} " "(neighborhoodMapId={}, owned={}, numPlots={})", plotIndex, neighborhoodMapId, owned, plots.size()); @@ -507,7 +507,7 @@ void HousingMap::SetPlotOwnershipState(uint8 plotIndex, bool owned) { if (plotData->WorldState != 0) { - TC_LOG_ERROR("housing", "SetPlotOwnershipState: Found plot {} with WorldState={}, " + TC_LOG_DEBUG("housing", "SetPlotOwnershipState: Found plot {} with WorldState={}, " "broadcasting to {} players", plotIndex, plotData->WorldState, std::distance(GetPlayers().begin(), GetPlayers().end())); @@ -520,7 +520,7 @@ void HousingMap::SetPlotOwnershipState(uint8 plotIndex, bool owned) HousingPlotOwnerType ownerType = GetPlotOwnerTypeForPlayer(mapPlayer, plotIndex); mapPlayer->SendUpdateWorldState(plotData->WorldState, static_cast(ownerType), false); - TC_LOG_ERROR("housing", "SetPlotOwnershipState: Sent WorldState {} = {} ({}) to player {}", + TC_LOG_DEBUG("housing", "SetPlotOwnershipState: Sent WorldState {} = {} ({}) to player {}", plotData->WorldState, uint32(ownerType), ownerType == HOUSING_PLOT_OWNER_SELF ? "SELF" : ownerType == HOUSING_PLOT_OWNER_FRIEND ? "FRIEND" : @@ -531,7 +531,7 @@ void HousingMap::SetPlotOwnershipState(uint8 plotIndex, bool owned) } else { - TC_LOG_ERROR("housing", "SetPlotOwnershipState: Plot {} matched but WorldState=0, skipping broadcast", + TC_LOG_DEBUG("housing", "SetPlotOwnershipState: Plot {} matched but WorldState=0, skipping broadcast", plotIndex); } break; @@ -1329,7 +1329,7 @@ void HousingMap::SendPerPlayerPlotWorldStates(Player* player) ++friendCount; } - TC_LOG_INFO("housing", "HousingMap::SendPerPlayerPlotWorldStates: Player {} ? sent {} WorldState updates " + TC_LOG_DEBUG("housing", "HousingMap::SendPerPlayerPlotWorldStates: Player {} ? sent {} WorldState updates " "(self={}, friend={}, {} plots had no WorldState ID in DB2)", player->GetGUID().ToString(), sentCount, selfCount, friendCount, noWsCount); } @@ -1454,35 +1454,9 @@ GameObject* HousingMap::SpawnHouseForPlot(uint8 plotIndex, Position const* custo // since DB2 HouseRotation X/Y are always 0 and the computed facing is a pure yaw). QuaternionData rot = QuaternionData::fromEulerAnglesZYX(facing, 0.0f, 0.0f); - // Spawn the platform WMO (GO entry 574432, GAMEOBJECT_TYPE_PHASEABLE_MO, displayId 113521). - // Retail sniff: each plot has a platform WMO that raises the house above terrain level. - // Some neighborhood maps have static platform spawns in the gameobject table (from sniffs); - // for maps without them, this dynamic spawn ensures a platform is always present. - { - constexpr uint32 PLATFORM_ENTRY = 574432; - Position platformPos(x, y, z, facing); - GameObject* platform = GameObject::CreateGameObject(PLATFORM_ENTRY, this, platformPos, rot, 255, GO_STATE_READY); - if (platform) - { - platform->SetFlag(GO_FLAG_NODESPAWN); - PhasingHandler::InitDbPhaseShift(platform->GetPhaseShift(), PHASE_USE_FLAGS_ALWAYS_VISIBLE, 0, 0); - if (!AddToMap(platform)) - { - TC_LOG_ERROR("housing", "HousingMap::SpawnHouseForPlot: Failed to add platform GO 574432 to map for plot {}", plotIndex); - delete platform; - } - else - { - TC_LOG_DEBUG("housing", "HousingMap::SpawnHouseForPlot: Spawned platform GO 574432 guid={} at ({:.2f},{:.2f},{:.2f}) facing={:.3f} for plot {}", - platform->GetGUID().ToString(), x, y, z, facing, plotIndex); - } - } - else - { - TC_LOG_ERROR("housing", "HousingMap::SpawnHouseForPlot: Failed to create platform GO 574432 for plot {} at ({:.2f},{:.2f},{:.2f})", - plotIndex, x, y, z); - } - } + // Platform WMO (GO entry 574432) is loaded from the static gameobject table (sniff data). + // Do NOT dynamically spawn a second platform ? it renders visibly on top of the static + // one and the static spawn already provides DynamicMapTree collision for ground-clamping. Position pos(x, y, z, facing); Neighborhood::PlotInfo const* plotInfo = _neighborhood->GetPlotInfo(plotIndex); @@ -1526,7 +1500,7 @@ GameObject* HousingMap::SpawnHouseForPlot(uint8 plotIndex, Position const* custo } // Spawn the front door GO (entry 586576, type Goober, displayId 116973) - // The interactive door GO must be at the actual doorway (top of stairs), NOT at + // The interactive door GO must be at the actual doorway (top of stairs), NOT at // the door mesh origin (which sits at stair base level, ~0.56 below house floor). // Door mesh local offset from base: (9.2805, -3.4555, -0.5611) ? mesh origin at stair foot // Adjusted offset: raised Z to door frame level, pulled X back toward actual door threshold. diff --git a/src/server/game/Housing/HousingMgr.cpp b/src/server/game/Housing/HousingMgr.cpp index 9212e1307..91dd70479 100644 --- a/src/server/game/Housing/HousingMgr.cpp +++ b/src/server/game/Housing/HousingMgr.cpp @@ -950,7 +950,7 @@ void HousingMgr::LoadNeighborhoodInitiativeData() data.RewardCurrencyID = entry->RewardCurrencyID; } - TC_LOG_DEBUG("housing", "HousingMgr::LoadNeighborhoodInitiativeData: Loaded {} NeighborhoodInitiative entries", uint32(_neighborhoodInitiativeStore.size())); + TC_LOG_INFO("housing", "HousingMgr::LoadNeighborhoodInitiativeData: Loaded {} NeighborhoodInitiative entries", uint32(_neighborhoodInitiativeStore.size())); } void HousingMgr::LoadRoomComponentData() diff --git a/src/server/game/Housing/InitiativeManager.cpp b/src/server/game/Housing/InitiativeManager.cpp index 4f3c85817..f1b7e2d05 100644 --- a/src/server/game/Housing/InitiativeManager.cpp +++ b/src/server/game/Housing/InitiativeManager.cpp @@ -46,6 +46,10 @@ void InitiativeManager::Initialize() BuildDB2IndexMaps(); LoadFromDB(); + // Auto-start initiatives for neighborhoods that don't have active ones. + // Must run AFTER LoadFromDB() and AFTER sNeighborhoodMgr.Initialize(). + CheckAndStartInitiatives(); + TC_LOG_INFO("housing", "InitiativeManager: Initialized with {} initiative definitions, {} active instances across all neighborhoods", uint32(sNeighborhoodInitiativeStore.GetNumRows()), [this]() -> uint32 { uint32 count = 0; @@ -775,15 +779,78 @@ void InitiativeManager::SendInitiativeServiceStatus(WorldSession* session, bool TC_LOG_DEBUG("housing", "InitiativeManager: Sent InitiativeServiceStatus (enabled={})", enabled); } -void InitiativeManager::SendPlayerInitiativeInfo(WorldSession* session, uint64 neighborhoodGuid) const +void InitiativeManager::SendPlayerInitiativeInfo(WorldSession* session, ObjectGuid const& neighborhoodGuid, uint64 neighborhoodLowGuid) const { WorldPackets::Housing::GetPlayerInitiativeInfoResult result; - result.Result = static_cast(HOUSING_RESULT_SUCCESS); + result.NeighborhoodGUID = neighborhoodGuid; - // Populate with current task progress for the active initiative - ActiveInitiative* active = GetActiveInitiative(neighborhoodGuid); + ActiveInitiative* active = GetActiveInitiative(neighborhoodLowGuid); if (active) { + result.HasInitiativeData = true; + + uint32 cycleID = GetActiveCycleForInitiative(active->InitiativeID); + + // Compute remaining duration from initiative start + cycle duration. + // Sniff-verified: RemainingDuration is in seconds (sniff value 972957 ? 11.25 days). + // If duration would be 0, use a 7-day fallback so the client shows the initiative + // as active (Duration=0 ? client treats as expired ? empty endeavor list). + int64 remainingDuration = 0; + { + int64 totalDurationSec = 0; + if (auto cycleIt = _initiativeActiveCycle.find(active->InitiativeID); cycleIt != _initiativeActiveCycle.end()) + { + if (InitiativeCycleEntry const* cycle = sInitiativeCycleStore.LookupEntry(cycleIt->second)) + totalDurationSec = static_cast(cycle->Duration) * 86400; + } + // Fallback: if DB2 has no duration, use 7 days + if (totalDurationSec <= 0) + totalDurationSec = 7 * 86400; + + int64 elapsed = GameTime::GetGameTime() - active->StartTime; + remainingDuration = totalDurationSec - elapsed; + + // If expired, reset the start time to now so the initiative stays active + if (remainingDuration <= 0) + { + active->StartTime = static_cast(GameTime::GetGameTime()); + remainingDuration = totalDurationSec; + } + } + + // Current milestone: find the highest milestone reached. + // Sniff-verified: ProgressRequired=1000.0 (the 0-1000 scale, not 0.0-1.0). + // active->Progress is stored as 0.0-1.0, so scale it to 0-1000 for comparison + // with DB2 milestones (which use the 0-1000 scale). + int32 currentMilestoneID = -1; + float progressRequired = 1000.0f; // Sniff: always 1000 + float currentProgress = active->Progress * 1000.0f; + auto msIt = _cycleMilestones.find(cycleID); + if (msIt != _cycleMilestones.end()) + { + for (auto const& ms : msIt->second) + { + if (currentProgress >= ms.ProgressRequired) + currentMilestoneID = static_cast(ms.MilestoneID); + if (progressRequired < ms.ProgressRequired) + progressRequired = ms.ProgressRequired; + } + } + + float playerContribution = 0.0f; + if (session->GetPlayer()) + playerContribution = static_cast( + GetPlayerContribution(neighborhoodLowGuid, active->InitiativeID, session->GetPlayer()->GetGUID().GetCounter())); + + result.RemainingDuration = remainingDuration; + result.CurrentInitiativeID = static_cast(active->InitiativeID); + result.CurrentMilestoneID = currentMilestoneID; + result.CurrentCycleID = static_cast(cycleID); + result.ProgressRequired = progressRequired; + result.CurrentProgress = currentProgress; + result.PlayerTotalContribution = playerContribution; + + // Populate task progress for (auto const& [taskId, taskProgress] : active->TaskProgress) { WorldPackets::Housing::JamPlayerInitiativeTaskInfo taskInfo; @@ -795,8 +862,8 @@ void InitiativeManager::SendPlayerInitiativeInfo(WorldSession* session, uint64 n } session->SendPacket(result.Write()); - TC_LOG_DEBUG("housing", "InitiativeManager: Sent GetPlayerInitiativeInfoResult with {} tasks for neighborhood {}", - uint32(result.Tasks.size()), neighborhoodGuid); + TC_LOG_DEBUG("housing", "InitiativeManager: Sent GetPlayerInitiativeInfoResult HasData={} InitID={} Tasks={} for neighborhood {}", + result.HasInitiativeData, result.CurrentInitiativeID, uint32(result.Tasks.size()), neighborhoodLowGuid); } void InitiativeManager::SendActivityLog(WorldSession* session, uint64 neighborhoodGuid) const @@ -940,6 +1007,34 @@ void InitiativeManager::BroadcastRewardAvailable(Neighborhood* neighborhood, uin void InitiativeManager::CheckAndStartInitiatives() { + // First, remove any active initiatives that have no tasks or no cycle defined. + // Task-less initiatives produce empty endeavor lists. + // Cycle-less initiatives produce CycleID=0 in the player fragment, causing the + // client's Lua UI to fail displaying the endeavor (no milestones, no duration). + for (auto& [nhGuid, initiatives] : _activeInitiatives) + { + std::erase_if(initiatives, [this](std::unique_ptr const& init) { + if (init->Completed) + return false; + + if (_initiativeTasks.find(init->InitiativeID) == _initiativeTasks.end()) + { + TC_LOG_INFO("housing", "InitiativeManager: Removing task-less initiative (DB2 ID {}) from neighborhood {}", + init->InitiativeID, init->NeighborhoodGuid); + return true; + } + + if (GetActiveCycleForInitiative(init->InitiativeID) == 0) + { + TC_LOG_INFO("housing", "InitiativeManager: Removing cycle-less initiative (DB2 ID {}) from neighborhood {}", + init->InitiativeID, init->NeighborhoodGuid); + return true; + } + + return false; + }); + } + // For each neighborhood that doesn't have an active initiative, start one for (Neighborhood* neighborhood : sNeighborhoodMgr.GetAllNeighborhoods()) { @@ -975,17 +1070,27 @@ void InitiativeManager::CheckAndStartInitiatives() } } - if (!recentlyCompleted) - { - // Look up cycle priority weight for this initiative's active cycle - uint32 cycleID = SelectWeightedCycle(entry->ID); - int32 weight = 1; // default equal weight - auto prioItr = _cyclePriorities.find(cycleID); - if (prioItr != _cyclePriorities.end() && !prioItr->second.empty()) - weight = std::max(1, prioItr->second[0].second); + if (recentlyCompleted) + continue; - candidates.emplace_back(entry->ID, weight); - } + // Skip initiatives that have no tasks defined ? they produce empty + // endeavor lists and waste a neighborhood's active initiative slot. + if (_initiativeTasks.find(entry->ID) == _initiativeTasks.end()) + continue; + + // Skip initiatives that have no cycle defined ? the client requires a + // valid CycleID to display milestones, duration, and rewards in the UI. + if (GetActiveCycleForInitiative(entry->ID) == 0) + continue; + + // Look up cycle priority weight for this initiative's active cycle + uint32 cycleID = SelectWeightedCycle(entry->ID); + int32 weight = 1; // default equal weight + auto prioItr = _cyclePriorities.find(cycleID); + if (prioItr != _cyclePriorities.end() && !prioItr->second.empty()) + weight = std::max(1, prioItr->second[0].second); + + candidates.emplace_back(entry->ID, weight); } if (!candidates.empty()) diff --git a/src/server/game/Housing/InitiativeManager.h b/src/server/game/Housing/InitiativeManager.h index 4232b29c0..af7e3b5ba 100644 --- a/src/server/game/Housing/InitiativeManager.h +++ b/src/server/game/Housing/InitiativeManager.h @@ -134,7 +134,7 @@ public: // Send packets to a session void SendInitiativeServiceStatus(WorldSession* session, bool enabled) const; - void SendPlayerInitiativeInfo(WorldSession* session, uint64 neighborhoodGuid) const; + void SendPlayerInitiativeInfo(WorldSession* session, ObjectGuid const& neighborhoodGuid, uint64 neighborhoodLowGuid) const; void SendActivityLog(WorldSession* session, uint64 neighborhoodGuid) const; void SendInitiativeRewardsResult(WorldSession* session, uint32 result) const; diff --git a/src/server/game/Housing/Neighborhood.cpp b/src/server/game/Housing/Neighborhood.cpp index 035b92b0f..34e03a334 100644 --- a/src/server/game/Housing/Neighborhood.cpp +++ b/src/server/game/Housing/Neighborhood.cpp @@ -85,12 +85,6 @@ bool Neighborhood::LoadFromDB(PreparedQueryResult neighborhood, PreparedQueryRes _plots[member.PlotIndex].PlotIndex = member.PlotIndex; _plots[member.PlotIndex].OwnerGuid = member.PlayerGuid; - // Resolve HouseGuid from character_housing JOIN (column 4) - uint64 houseId = memberFields[4].GetUInt64(); - if (houseId != 0) - _plots[member.PlotIndex].HouseGuid = ObjectGuid::Create( - /*subType*/ 3, /*arg1*/ sRealmList->GetCurrentRealmId().Realm, /*arg2*/ 7, houseId); - // Resolve BNet account GUID from characters.account JOIN (column 5). // The client requires non-zero HouseOwnerBnetAccountGUID on the plot AreaTrigger's // FHousingPlotAreaTrigger_C fragment for IsInsidePlot() validation. @@ -99,7 +93,13 @@ bool Neighborhood::LoadFromDB(PreparedQueryResult neighborhood, PreparedQueryRes { uint32 bnetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(gameAccountId); if (bnetAccountId != 0) + { _plots[member.PlotIndex].OwnerBnetGuid = ObjectGuid::Create(bnetAccountId); + // HouseGuid counter MUST match HousingPlayerHouseEntity GUID (WorldSession.cpp), + // which uses battlenetAccountId. Using ch.houseId (DB2 entry) was wrong. + _plots[member.PlotIndex].HouseGuid = ObjectGuid::Create( + /*subType*/ 3, /*arg1*/ sRealmList->GetCurrentRealmId().Realm, /*arg2*/ 7, uint64(bnetAccountId)); + } } } } while (members->NextRow()); diff --git a/src/server/game/Server/Packets/HousingPackets.cpp b/src/server/game/Server/Packets/HousingPackets.cpp index a233b4fb6..cf1a5db2d 100644 --- a/src/server/game/Server/Packets/HousingPackets.cpp +++ b/src/server/game/Server/Packets/HousingPackets.cpp @@ -1994,7 +1994,22 @@ namespace WorldPackets::Housing WorldPacket const* GetPlayerInitiativeInfoResult::Write() { - _worldPacket << uint8(Result); + _worldPacket << NeighborhoodGUID; + _worldPacket.WriteBit(HasError); + _worldPacket.WriteBit(HasInitiativeData); + _worldPacket.FlushBits(); + + if (HasInitiativeData) + { + _worldPacket << int64(RemainingDuration); + _worldPacket << int32(CurrentInitiativeID); + _worldPacket << int32(CurrentMilestoneID); + _worldPacket << int32(CurrentCycleID); + _worldPacket << float(ProgressRequired); + _worldPacket << float(CurrentProgress); + _worldPacket << float(PlayerTotalContribution); + } + _worldPacket << uint32(Tasks.size()); for (auto const& task : Tasks) { @@ -2003,9 +2018,9 @@ namespace WorldPackets::Housing _worldPacket << uint32(task.Status); } - TC_LOG_DEBUG("network.opcode", "SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT Result: {} TaskCount: {}", Result, Tasks.size()); - for (size_t i = 0; i < Tasks.size(); ++i) - TC_LOG_DEBUG("network.opcode", " Task[{}]: TaskID={} Progress={} Status={}", i, Tasks[i].TaskID, Tasks[i].Progress, Tasks[i].Status); + TC_LOG_DEBUG("network.opcode", "SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT NH={} Error={} HasData={} InitID={} CycleID={} Progress={:.1f}/{:.0f} Tasks={}", + NeighborhoodGUID.ToString(), HasError, HasInitiativeData, + CurrentInitiativeID, CurrentCycleID, CurrentProgress, ProgressRequired, Tasks.size()); return &_worldPacket; } @@ -2781,6 +2796,7 @@ namespace WorldPackets::Neighborhood void InitiativeReportProgress::Read() { _worldPacket >> NeighborhoodGuid; + TC_LOG_DEBUG("network.opcode", "CMSG_INITIATIVE_REPORT_PROGRESS NeighborhoodGuid: {}", NeighborhoodGuid.ToString()); } diff --git a/src/server/game/Server/Packets/HousingPackets.h b/src/server/game/Server/Packets/HousingPackets.h index 6d0873f0e..0158966a7 100644 --- a/src/server/game/Server/Packets/HousingPackets.h +++ b/src/server/game/Server/Packets/HousingPackets.h @@ -56,16 +56,17 @@ namespace WorldPackets::Housing // IDA-verified wire format for house/resident entries nested inside neighborhood data. // Deserializer: Deserialize_ResidentArray (0x7FF724C3EEF0), stride 80 bytes in memory. - // Wire: PackedGUID + PackedGUID + PackedGUID + uint8 + uint32 + uint8(bit7=hasOpt) [+ uint64] + // Wire order: PackedGUID(House) + PackedGUID(Owner) + PackedGUID(Neighborhood) + uint8 + uint32 + uint8(bit7=hasOpt) [+ uint64] + // IDA proof: offset-0 GUID compared vs house records; offset-16 GUID passed to ai_Process_PlayerContextUpdate (name lookup). struct JamCliHouse { - ObjectGuid OwnerGUID; // offset 0: house owner player GUID - ObjectGuid HouseGUID; // offset 16: house entity GUID - ObjectGuid NeighborhoodGUID; // offset 32: neighborhood GUID (matched by client against SetViewingNeighborhood stored value) - uint8 HouseLevel = 0; // offset 48 - uint32 PlotIndex = 0; // offset 72 - bool HasOptionalField = false; // offset 64: derived from bit 7 of wire uint8 - uint64 OptionalValue = 0; // offset 56: only present if HasOptionalField + ObjectGuid HouseGUID; // wire pos 1, client offset 0: house entity GUID (compared vs HouseInfo records) + ObjectGuid OwnerGUID; // wire pos 2, client offset 16: owner player GUID (used for name lookup) + ObjectGuid NeighborhoodGUID; // wire pos 3, client offset 32: neighborhood GUID + uint8 HouseLevel = 0; // client offset 48 + uint32 PlotIndex = 0; // client offset 72 + bool HasOptionalField = false; // client offset 64: derived from bit 7 of wire uint8 + uint64 OptionalValue = 0; // client offset 56: only present if HasOptionalField }; // IDA-verified wire format for neighborhood entries in house finder responses. @@ -2096,7 +2097,20 @@ namespace WorldPackets::Housing public: GetPlayerInitiativeInfoResult() : ServerPacket(SMSG_GET_PLAYER_INITIATIVE_INFO_RESULT) {} WorldPacket const* Write() override; - uint8 Result = 0; + + ObjectGuid NeighborhoodGUID; + bool HasError = false; + bool HasInitiativeData = false; + + // InitiativeInfo block (only written when HasInitiativeData = true) + int64 RemainingDuration = 0; + int32 CurrentInitiativeID = 0; + int32 CurrentMilestoneID = -1; + int32 CurrentCycleID = 0; + float ProgressRequired = 0.0f; + float CurrentProgress = 0.0f; + float PlayerTotalContribution = 0.0f; + std::vector Tasks; }; diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index ffc50583c..23b71dc4d 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -125,8 +125,8 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun _accountId(id), _accountName(std::move(name)), _battlenetAccount(new Battlenet::Account(this, ObjectGuid::Create(battlenetAccountId), std::move(battlenetAccountEmail))), - _housingPlayerHouseEntity(new HousingPlayerHouseEntity(this, ObjectGuid::Create(/*subType*/3, /*arg1*/1, /*arg2*/7, /*arg3*/battlenetAccountId))), - _housingNeighborhoodMirrorEntity(new HousingNeighborhoodMirrorEntity(this, ObjectGuid::Create(/*subType*/4, /*arg1*/2, /*arg2*/0, /*arg3*/battlenetAccountId))), + _housingPlayerHouseEntity(new HousingPlayerHouseEntity(this, ObjectGuid::Create(/*subType*/3, /*arg1*/sRealmList->GetCurrentRealmId().Realm, /*arg2*/7, /*arg3*/battlenetAccountId))), + _housingNeighborhoodMirrorEntity(new HousingNeighborhoodMirrorEntity(this, ObjectGuid::Create(/*subType*/4, /*arg1*/sRealmList->GetCurrentRealmId().Realm, /*arg2*/0, /*arg3*/battlenetAccountId))), m_accountExpansion(expansion), m_expansion(std::min(expansion, sWorld->getIntConfig(CONFIG_EXPANSION))), _os(std::move(os)),