diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-12-16 00:09:26 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-12-16 00:09:26 +0100 |
| commit | bd2b12fa36830c6b12e124359f46ac974d554080 (patch) | |
| tree | bf34422aeca361b8027256d53c80777865ae2933 /src/server/game/Entities/Object | |
| parent | af57aa29dcfc9f25dba794883f0180a22ce28133 (diff) | |
Core: Updated to 11.2.7
Diffstat (limited to 'src/server/game/Entities/Object')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 18 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/ObjectGuid.cpp | 100 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/ObjectGuid.h | 27 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.cpp | 1940 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 806 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h | 98 |
7 files changed, 2390 insertions, 602 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 8375032413f..ac2219ed5cf 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -320,6 +320,9 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe data->WriteBit(flags.SceneObject); data->WriteBit(flags.ActivePlayer); data->WriteBit(flags.Conversation); + data->WriteBit(flags.Room); + data->WriteBit(flags.Decor); + data->WriteBit(flags.MeshObject); data->FlushBits(); if (flags.MovementUpdate) @@ -494,6 +497,21 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe *data << uint64(gameObject->GetPackedLocalRotation()); // Rotation } + //if (flags.Room) + // *data << ObjectGuid(HouseGUID); + + //if (flags.Decor) + // *data << ObjectGuid(RoomGUID); + + //if (flags.MeshObject) + //{ + // *data << ObjectGuid(AttachParentGUID); + // *data << TaggedPosition<Position::XYZ>(PositionLocalSpace); + // *data << QuaternionData(RotationLocalSpace); + // *data << float(ScaleLocalSpace); + // *data << uint8(AttachmentFlags); + //} + if (PauseTimes && !PauseTimes->empty()) data->append(PauseTimes->data(), PauseTimes->size()); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index d9f8e039392..72b3a5dd448 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -99,6 +99,9 @@ struct CreateObjectBits bool SceneObject : 1; bool ActivePlayer : 1; bool Conversation : 1; + bool Room : 1; + bool Decor : 1; + bool MeshObject : 1; void Clear() { diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index 069c4658533..b5510dc9eb2 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -659,6 +659,74 @@ namespace return ObjectGuidFactory::CreateLMMLobby(realmId, arg2, arg3, arg4, arg5); } + static fmt::appender FormatHousing(fmt::format_context& ctx, std::string_view typeName, ObjectGuid const& guid) + { + ctx.advance_to(AppendTypeName(ctx, typeName)); + switch (uint32 subType = (guid.GetRawValue(1) >> 53) & 0x1F) + { + case 1: + case 4: + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, subType)); + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, uint32(guid.GetRawValue(1) >> 32) & 0xFFFF)); + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, uint32(guid.GetRawValue(1)) & 0xFFFFFFFF)); + ctx.advance_to(AppendComponent<no_padding, hex>(ctx, guid.GetRawValue(0))); + break; + case 2: + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, subType)); + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, uint32(guid.GetRawValue(1)) & 0xFFFFFFFF)); + ctx.advance_to(AppendComponent<no_padding, hex>(ctx, guid.GetRawValue(0))); + break; + case 3: + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, subType)); + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, uint32(guid.GetRawValue(1)) & 0x7FFF)); + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, guid.GetRawValue(0))); + ctx.advance_to(AppendComponent<no_padding, dec>(ctx, uint32(guid.GetRawValue(1) >> 15) & 0x3F)); + break; + default: + break; + } + return ctx.out(); + } + + static ObjectGuid ParseHousing(HighGuid /*type*/, std::string_view guidString) + { + uint32 subType = 0; + + if (!ParseComponent<dec>(guidString, &subType)) + return ObjectGuid::FromStringFailed; + + uint32 arg1 = 0; + uint32 arg2 = 0; + uint64 arg3 = UI64LIT(0); + + switch (subType) + { + case 1: + case 4: + if (!ParseComponent<dec>(guidString, &arg1) + || !ParseComponent<dec>(guidString, &arg2) + || !ParseComponent<hex>(guidString, &arg3) + || !ParseDone(guidString)) + return ObjectGuid::FromStringFailed; + break; + case 2: + if (!ParseComponent<dec>(guidString, &arg2) + || !ParseComponent<hex>(guidString, &arg3) + || !ParseDone(guidString)) + return ObjectGuid::FromStringFailed; + break; + case 3: + if (!ParseComponent<dec>(guidString, &arg2) + || !ParseComponent<dec>(guidString, &arg3) + || !ParseComponent<dec>(guidString, &arg1) + || !ParseDone(guidString)) + return ObjectGuid::FromStringFailed; + break; + } + + return ObjectGuidFactory::CreateHousing(subType, arg1, arg2, arg3); + } + ObjectGuidInfo(); } Info; @@ -724,6 +792,9 @@ namespace SET_GUID_INFO(ArenaTeam, FormatGuild, ParseGuild); SET_GUID_INFO(LMMParty, FormatClient, ParseClient); SET_GUID_INFO(LMMLobby, FormatLMMLobby, ParseLMMLobby); + SET_GUID_INFO(Housing, FormatHousing, ParseHousing); + SET_GUID_INFO(MeshObject, FormatWorldObject, ParseWorldObject); + SET_GUID_INFO(Entity, FormatWorldObject, ParseWorldObject); #undef SET_GUID_INFO } @@ -952,6 +1023,35 @@ ObjectGuid ObjectGuidFactory::CreateLMMLobby(uint32 realmId, uint32 arg2, uint8 counter); } +ObjectGuid ObjectGuidFactory::CreateHousing(uint32 subType, uint32 arg1, uint32 arg2, uint64 arg3) +{ + switch (subType) + { + case 1: + case 4: + return ObjectGuid(uint64((uint64(HighGuid::Housing) << 58) + | (uint64(subType & 0x1F) << 53) + | (uint64(arg1 & 0xFFFF) << 32) + | (uint64(arg2 & 0xFFFFFFFF))), + arg3); + case 2: + return ObjectGuid(uint64((uint64(HighGuid::Housing) << 58) + | (uint64(subType & 0x1F) << 53) + | (uint64(arg2 & 0xFFFFFFFF))), + arg3); + case 3: + return ObjectGuid(uint64((uint64(HighGuid::Housing) << 58) + | (uint64(subType & 0x1F) << 53) + | (uint64(arg1 & 0x3F) << 15) + | (uint64(arg2 & 0x7FFF))), + arg3); + default: + break; + } + + return ObjectGuid::Empty; +} + ObjectGuid const ObjectGuid::Empty = ObjectGuid::Create<HighGuid::Null>(); ObjectGuid const ObjectGuid::ToStringFailed = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(3)); ObjectGuid const ObjectGuid::FromStringFailed = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(4)); diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index 51744804ffa..98cf4c5632a 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -47,10 +47,14 @@ enum TypeID : uint8 TYPEID_CORPSE = 10, TYPEID_AREATRIGGER = 11, TYPEID_SCENEOBJECT = 12, - TYPEID_CONVERSATION = 13 + TYPEID_CONVERSATION = 13, + TYPEID_MESH_OBJECT = 14, + TYPEID_AI_GROUP = 15, + TYPEID_SCENARIO = 16, + TYPEID_LOOT_OBJECT = 17 }; -#define NUM_CLIENT_OBJECT_TYPES 14 +#define NUM_CLIENT_OBJECT_TYPES 18 enum TypeMask { @@ -68,6 +72,10 @@ enum TypeMask TYPEMASK_AREATRIGGER = 1 << TYPEID_AREATRIGGER, TYPEMASK_SCENEOBJECT = 1 << TYPEID_SCENEOBJECT, TYPEMASK_CONVERSATION = 1 << TYPEID_CONVERSATION, + TYPEMASK_MESH_OBJECT = 1 << TYPEID_MESH_OBJECT, + TYPEMASK_AI_GROUP = 1 << TYPEID_AI_GROUP, + TYPEMASK_SCENARIO = 1 << TYPEID_SCENARIO, + TYPEMASK_LOOT_OBJECT = 1 << TYPEID_LOOT_OBJECT, TYPEMASK_SEER = TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_DYNAMICOBJECT, TYPEMASK_WORLDOBJECT = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_DYNAMICOBJECT | TYPEMASK_CORPSE | TYPEMASK_AREATRIGGER | TYPEMASK_SCENEOBJECT | TYPEMASK_CONVERSATION @@ -88,7 +96,11 @@ inline constexpr std::array<uint32, NUM_CLIENT_OBJECT_TYPES> ObjectTypeMask = TYPEMASK_OBJECT | TYPEMASK_CORPSE, TYPEMASK_OBJECT | TYPEMASK_AREATRIGGER, TYPEMASK_OBJECT | TYPEMASK_SCENEOBJECT, - TYPEMASK_OBJECT | TYPEMASK_CONVERSATION + TYPEMASK_OBJECT | TYPEMASK_CONVERSATION, + TYPEMASK_OBJECT | TYPEMASK_MESH_OBJECT, + TYPEMASK_OBJECT | TYPEMASK_AI_GROUP, + TYPEMASK_OBJECT | TYPEMASK_SCENARIO, + TYPEMASK_OBJECT | TYPEMASK_LOOT_OBJECT, }; enum class HighGuid @@ -148,6 +160,9 @@ enum class HighGuid ArenaTeam = 52, LMMParty = 53, LMMLobby = 54, + Housing = 55, + MeshObject = 56, + Entity = 57, Count, }; @@ -183,6 +198,7 @@ enum class ObjectGuidFormatType ToolsClient, WorldLayer, LMMLobby, + Housing, }; template<HighGuid high> @@ -254,6 +270,9 @@ MAKE_GUID_TRAIT(HighGuid::WorldLayer, ObjectGuidSequenceSource::Global, ObjectGu MAKE_GUID_TRAIT(HighGuid::ArenaTeam, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Guild); MAKE_GUID_TRAIT(HighGuid::LMMParty, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Client); MAKE_GUID_TRAIT(HighGuid::LMMLobby, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::LMMLobby); +MAKE_GUID_TRAIT(HighGuid::Housing, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::Housing); +MAKE_GUID_TRAIT(HighGuid::MeshObject, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject); +MAKE_GUID_TRAIT(HighGuid::Entity, ObjectGuidSequenceSource::Map, ObjectGuidFormatType::WorldObject); class ByteBuffer; class ObjectGuid; @@ -280,6 +299,7 @@ public: static ObjectGuid CreateToolsClient(uint16 mapId, uint32 serverId, uint64 counter); static ObjectGuid CreateWorldLayer(uint32 arg1, uint16 arg2, uint8 arg3, uint32 arg4); static ObjectGuid CreateLMMLobby(uint32 realmId, uint32 arg2, uint8 arg3, uint8 arg4, uint64 counter); + static ObjectGuid CreateHousing(uint32 subType, uint32 arg1, uint32 arg2, uint64 arg3); }; class TC_GAME_API ObjectGuid @@ -397,6 +417,7 @@ class TC_GAME_API ObjectGuid template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::ToolsClient, int32> = 0> static ObjectGuid Create(uint16 mapId, uint32 serverId, LowType counter) { return ObjectGuidFactory::CreateToolsClient(mapId, serverId, counter); } template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::WorldLayer, int32> = 0> static ObjectGuid Create(uint32 arg1, uint16 arg2, uint8 arg3, uint32 arg4) { return ObjectGuidFactory::CreateWorldLayer(arg1, arg2, arg3, arg4); } template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::LMMLobby, int32> = 0> static ObjectGuid Create(uint32 arg2, uint8 arg3, uint8 arg4, LowType counter) { return ObjectGuidFactory::CreateLMMLobby(0, arg2, arg3, arg4, counter); } + template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Housing, int32> = 0> static ObjectGuid Create(uint32 subType, uint32 arg1, uint32 arg2, uint64 arg3) { return ObjectGuidFactory::CreateHousing(subType, arg1, arg2, arg3); } protected: constexpr ObjectGuid(uint64 high, uint64 low) : _data({{ low, high }}) diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 7df3bcb97a5..1f80091cb59 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -1029,6 +1029,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi data << uint8(ClassId); data << uint8(PlayerClassId); data << uint8(Sex); + data << uint8(CreatureType); data << uint8(DisplayPower); data << uint32(OverrideDisplayPowerID); data << int64(Health); @@ -1075,7 +1076,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi data << float(CombatReach); data << float(DisplayScale); data << int32(CreatureFamily); - data << uint8(CreatureType); + data << uint8(OverrideCreatureType); data << int32(NativeDisplayID); data << float(NativeXDisplayScale); data << int32(MountDisplayID); @@ -1214,11 +1215,11 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi static constexpr void UnitDataAppendAllowedFieldsMaskForFlag(UnitData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array<uint32, 7>{ 0x00010000u, 0xF0040000u, 0xFF080000u, 0x000007FEu, 0xE0000100u, 0xFF01FFFFu, 0x7FFFFFFFu }; + allowedMaskForTarget |= std::array<uint32, 7>{ 0x00010000u, 0xE0080000u, 0xFE100002u, 0x00000FFEu, 0xC0000200u, 0xFE03FFFFu, 0xFFFFFFFFu }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) - allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xE0000100u, 0x0001FFFFu, 0x00000000u }; + allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xC0000200u, 0x0003FFFFu, 0x00000000u }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) - allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0xF0000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0001FE00u }; + allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0xE0000000u, 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0003FC00u }; } void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) @@ -1228,14 +1229,14 @@ void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFl void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x1FFFFFFFu, 0x00FE0000u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x1FF7FFFFu, 0x01EFFFFDu, 0xFFFFF001u, 0x3FFFFFFFu, 0x01FC0000u, 0x00000000u }); UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const { - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x1FFFFFFFu, 0x00FE0000u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x1FF7FFFFu, 0x01EFFFFDu, 0xFFFFF001u, 0x3FFFFFFFu, 0x01FC0000u, 0x00000000u }); UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -1432,412 +1433,416 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor { if (changesMask[33]) { - data << uint8(DisplayPower); + data << uint8(CreatureType); } if (changesMask[34]) { - data << uint32(OverrideDisplayPowerID); + data << uint8(DisplayPower); } if (changesMask[35]) { - data << int64(Health); + data << uint32(OverrideDisplayPowerID); } if (changesMask[36]) { - data << int64(MaxHealth); + data << int64(Health); } if (changesMask[37]) { - data << int32(Level); + data << int64(MaxHealth); } if (changesMask[38]) { - data << int32(EffectiveLevel); + data << int32(Level); } if (changesMask[39]) { - data << int32(ContentTuningID); + data << int32(EffectiveLevel); } if (changesMask[40]) { - data << int32(ScalingLevelMin); + data << int32(ContentTuningID); } if (changesMask[41]) { - data << int32(ScalingLevelMax); + data << int32(ScalingLevelMin); } if (changesMask[42]) { - data << int32(ScalingLevelDelta); + data << int32(ScalingLevelMax); } if (changesMask[43]) { - data << uint8(ScalingFactionGroup); + data << int32(ScalingLevelDelta); } if (changesMask[44]) { - data << int32(ViewerDependentValue<FactionTemplateTag>::GetValue(this, owner, receiver)); + data << uint8(ScalingFactionGroup); } if (changesMask[45]) { - data << uint32(ViewerDependentValue<FlagsTag>::GetValue(this, owner, receiver)); + data << int32(ViewerDependentValue<FactionTemplateTag>::GetValue(this, owner, receiver)); } if (changesMask[46]) { - data << uint32(ViewerDependentValue<Flags2Tag>::GetValue(this, owner, receiver)); + data << uint32(ViewerDependentValue<FlagsTag>::GetValue(this, owner, receiver)); } if (changesMask[47]) { - data << uint32(ViewerDependentValue<Flags3Tag>::GetValue(this, owner, receiver)); + data << uint32(ViewerDependentValue<Flags2Tag>::GetValue(this, owner, receiver)); } if (changesMask[48]) { - data << uint32(ViewerDependentValue<Flags4Tag>::GetValue(this, owner, receiver)); + data << uint32(ViewerDependentValue<Flags3Tag>::GetValue(this, owner, receiver)); } if (changesMask[49]) { - data << uint32(ViewerDependentValue<AuraStateTag>::GetValue(this, owner, receiver)); + data << uint32(ViewerDependentValue<Flags4Tag>::GetValue(this, owner, receiver)); } if (changesMask[50]) { - data << uint32(RangedAttackRoundBaseTime); + data << uint32(ViewerDependentValue<AuraStateTag>::GetValue(this, owner, receiver)); } if (changesMask[51]) { - data << float(BoundingRadius); + data << uint32(RangedAttackRoundBaseTime); } if (changesMask[52]) { - data << float(CombatReach); + data << float(BoundingRadius); } if (changesMask[53]) { - data << float(DisplayScale); + data << float(CombatReach); } if (changesMask[54]) { - data << int32(CreatureFamily); + data << float(DisplayScale); } if (changesMask[55]) { - data << uint8(CreatureType); + data << int32(CreatureFamily); } if (changesMask[56]) { - data << int32(NativeDisplayID); + data << uint8(OverrideCreatureType); } if (changesMask[57]) { - data << float(NativeXDisplayScale); + data << int32(NativeDisplayID); } if (changesMask[58]) { - data << int32(MountDisplayID); + data << float(NativeXDisplayScale); } if (changesMask[59]) { - data << int32(CosmeticMountDisplayID); + data << int32(MountDisplayID); } if (changesMask[60]) { - data << float(MinDamage); + data << int32(CosmeticMountDisplayID); } if (changesMask[61]) { - data << float(MaxDamage); + data << float(MinDamage); } if (changesMask[62]) { - data << float(MinOffHandDamage); + data << float(MaxDamage); } if (changesMask[63]) { - data << float(MaxOffHandDamage); + data << float(MinOffHandDamage); } } if (changesMask[64]) { if (changesMask[65]) { - data << uint8(StandState); + data << float(MaxOffHandDamage); } if (changesMask[66]) { - data << uint8(PetTalentPoints); + data << uint8(StandState); } if (changesMask[67]) { - data << uint8(VisFlags); + data << uint8(PetTalentPoints); } if (changesMask[68]) { - data << uint8(AnimTier); + data << uint8(VisFlags); } if (changesMask[69]) { - data << uint32(PetNumber); + data << uint8(AnimTier); } if (changesMask[70]) { - data << uint32(PetNameTimestamp); + data << uint32(PetNumber); } if (changesMask[71]) { - data << uint32(PetExperience); + data << uint32(PetNameTimestamp); } if (changesMask[72]) { - data << uint32(PetNextLevelExperience); + data << uint32(PetExperience); } if (changesMask[73]) { - data << float(ModCastingSpeed); + data << uint32(PetNextLevelExperience); } if (changesMask[74]) { - data << float(ModCastingSpeedNeg); + data << float(ModCastingSpeed); } if (changesMask[75]) { - data << float(ModSpellHaste); + data << float(ModCastingSpeedNeg); } if (changesMask[76]) { - data << float(ModHaste); + data << float(ModSpellHaste); } if (changesMask[77]) { - data << float(ModRangedHaste); + data << float(ModHaste); } if (changesMask[78]) { - data << float(ModHasteRegen); + data << float(ModRangedHaste); } if (changesMask[79]) { - data << float(ModTimeRate); + data << float(ModHasteRegen); } if (changesMask[80]) { - data << int32(CreatedBySpell); + data << float(ModTimeRate); } if (changesMask[81]) { - data << int32(EmoteState); + data << int32(CreatedBySpell); } if (changesMask[82]) { - data << int32(BaseMana); + data << int32(EmoteState); } if (changesMask[83]) { - data << int32(BaseHealth); + data << int32(BaseMana); } if (changesMask[84]) { - data << uint8(SheatheState); + data << int32(BaseHealth); } if (changesMask[85]) { - data << uint8(ViewerDependentValue<PvpFlagsTag>::GetValue(this, owner, receiver)); + data << uint8(SheatheState); } if (changesMask[86]) { - data << uint8(PetFlags); + data << uint8(ViewerDependentValue<PvpFlagsTag>::GetValue(this, owner, receiver)); } if (changesMask[87]) { - data << uint8(ShapeshiftForm); + data << uint8(PetFlags); } if (changesMask[88]) { - data << int32(AttackPower); + data << uint8(ShapeshiftForm); } if (changesMask[89]) { - data << int32(AttackPowerModPos); + data << int32(AttackPower); } if (changesMask[90]) { - data << int32(AttackPowerModNeg); + data << int32(AttackPowerModPos); } if (changesMask[91]) { - data << float(AttackPowerMultiplier); + data << int32(AttackPowerModNeg); } if (changesMask[92]) { - data << int32(AttackPowerModSupport); + data << float(AttackPowerMultiplier); } if (changesMask[93]) { - data << int32(RangedAttackPower); + data << int32(AttackPowerModSupport); } if (changesMask[94]) { - data << int32(RangedAttackPowerModPos); + data << int32(RangedAttackPower); } if (changesMask[95]) { - data << int32(RangedAttackPowerModNeg); + data << int32(RangedAttackPowerModPos); } } if (changesMask[96]) { if (changesMask[97]) { - data << float(RangedAttackPowerMultiplier); + data << int32(RangedAttackPowerModNeg); } if (changesMask[98]) { - data << int32(RangedAttackPowerModSupport); + data << float(RangedAttackPowerMultiplier); } if (changesMask[99]) { - data << int32(MainHandWeaponAttackPower); + data << int32(RangedAttackPowerModSupport); } if (changesMask[100]) { - data << int32(OffHandWeaponAttackPower); + data << int32(MainHandWeaponAttackPower); } if (changesMask[101]) { - data << int32(RangedWeaponAttackPower); + data << int32(OffHandWeaponAttackPower); } if (changesMask[102]) { - data << int32(SetAttackSpeedAura); + data << int32(RangedWeaponAttackPower); } if (changesMask[103]) { - data << float(Lifesteal); + data << int32(SetAttackSpeedAura); } if (changesMask[104]) { - data << float(MinRangedDamage); + data << float(Lifesteal); } if (changesMask[105]) { - data << float(MaxRangedDamage); + data << float(MinRangedDamage); } if (changesMask[106]) { - data << float(ManaCostMultiplier); + data << float(MaxRangedDamage); } if (changesMask[107]) { - data << float(MaxHealthModifier); + data << float(ManaCostMultiplier); } if (changesMask[108]) { - data << float(HoverHeight); + data << float(MaxHealthModifier); } if (changesMask[109]) { - data << int32(MinItemLevelCutoff); + data << float(HoverHeight); } if (changesMask[110]) { - data << int32(MinItemLevel); + data << int32(MinItemLevelCutoff); } if (changesMask[111]) { - data << int32(MaxItemLevel); + data << int32(MinItemLevel); } if (changesMask[112]) { - data << int32(AzeriteItemLevel); + data << int32(MaxItemLevel); } if (changesMask[113]) { - data << int32(WildBattlePetLevel); + data << int32(AzeriteItemLevel); } if (changesMask[114]) { - data << int32(BattlePetCompanionExperience); + data << int32(WildBattlePetLevel); } if (changesMask[115]) { - data << uint32(BattlePetCompanionNameTimestamp); + data << int32(BattlePetCompanionExperience); } if (changesMask[116]) { - data << int32(ViewerDependentValue<InteractSpellIDTag>::GetValue(this, owner, receiver)); + data << uint32(BattlePetCompanionNameTimestamp); } if (changesMask[117]) { - data << int32(ScaleDuration); + data << int32(ViewerDependentValue<InteractSpellIDTag>::GetValue(this, owner, receiver)); } if (changesMask[118]) { - data << int32(LooksLikeMountID); + data << int32(ScaleDuration); } if (changesMask[119]) { - data << int32(LooksLikeCreatureID); + data << int32(LooksLikeMountID); } if (changesMask[120]) { - data << int32(LookAtControllerID); + data << int32(LooksLikeCreatureID); } if (changesMask[121]) { - data << int32(PerksVendorItemID); + data << int32(LookAtControllerID); } if (changesMask[122]) { - data << int32(TaxiNodesID); + data << int32(PerksVendorItemID); } if (changesMask[123]) { - data << *GuildGUID; + data << int32(TaxiNodesID); } if (changesMask[124]) { - data << int32(FlightCapabilityID); + data << *GuildGUID; } if (changesMask[125]) { - data << float(GlideEventSpeedDivisor); + data << int32(FlightCapabilityID); } if (changesMask[126]) { - data << int32(DriveCapabilityID); + data << float(GlideEventSpeedDivisor); } if (changesMask[127]) { - data << int32(MaxHealthModifierFlatNeg); + data << int32(DriveCapabilityID); } } if (changesMask[128]) { if (changesMask[129]) { - data << int32(MaxHealthModifierFlatPos); + data << int32(MaxHealthModifierFlatNeg); } if (changesMask[130]) { - data << uint32(SilencedSchoolMask); + data << int32(MaxHealthModifierFlatPos); } if (changesMask[131]) { - data << uint32(CurrentAreaID); + data << uint32(SilencedSchoolMask); } if (changesMask[132]) { - data << float(Field_31C); + data << uint32(CurrentAreaID); } if (changesMask[133]) { - data << float(Field_320); + data << float(Field_31C); } if (changesMask[134]) { + data << float(Field_320); + } + if (changesMask[135]) + { data << *NameplateAttachToGUID; } data.WriteBits(AssistActionData.has_value(), 1); data.FlushBits(); - if (changesMask[135]) + if (changesMask[136]) { if (AssistActionData.has_value()) { @@ -1845,83 +1850,83 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor } } } - if (changesMask[136]) + if (changesMask[137]) { for (uint32 i = 0; i < 10; ++i) { - if (changesMask[137 + i]) + if (changesMask[138 + i]) { data << int32(Power[i]); } - if (changesMask[147 + i]) + if (changesMask[148 + i]) { data << int32(MaxPower[i]); } - if (changesMask[157 + i]) + if (changesMask[158 + i]) { data << float(PowerRegenFlatModifier[i]); } - if (changesMask[167 + i]) + if (changesMask[168 + i]) { data << float(PowerRegenInterruptedFlatModifier[i]); } } } - if (changesMask[177]) + if (changesMask[178]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[178 + i]) + if (changesMask[179 + i]) { VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[181]) + if (changesMask[182]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[182 + i]) + if (changesMask[183 + i]) { data << uint32(AttackRoundBaseTime[i]); } } } - if (changesMask[184]) + if (changesMask[185]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[185 + i]) + if (changesMask[186 + i]) { data << int32(Stats[i]); } - if (changesMask[189 + i]) + if (changesMask[190 + i]) { data << int32(StatPosBuff[i]); } - if (changesMask[193 + i]) + if (changesMask[194 + i]) { data << int32(StatNegBuff[i]); } - if (changesMask[197 + i]) + if (changesMask[198 + i]) { data << int32(StatSupportBuff[i]); } } } - if (changesMask[201]) + if (changesMask[202]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[202 + i]) + if (changesMask[203 + i]) { data << int32(Resistances[i]); } - if (changesMask[209 + i]) + if (changesMask[210 + i]) { data << int32(BonusResistanceMods[i]); } - if (changesMask[216 + i]) + if (changesMask[217 + i]) { data << int32(ManaCostModifier[i]); } @@ -1963,6 +1968,7 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(ClassId); Base::ClearChangesMask(PlayerClassId); Base::ClearChangesMask(Sex); + Base::ClearChangesMask(CreatureType); Base::ClearChangesMask(DisplayPower); Base::ClearChangesMask(OverrideDisplayPowerID); Base::ClearChangesMask(Health); @@ -1985,7 +1991,7 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(CombatReach); Base::ClearChangesMask(DisplayScale); Base::ClearChangesMask(CreatureFamily); - Base::ClearChangesMask(CreatureType); + Base::ClearChangesMask(OverrideCreatureType); Base::ClearChangesMask(NativeDisplayID); Base::ClearChangesMask(NativeXDisplayScale); Base::ClearChangesMask(MountDisplayID); @@ -2107,6 +2113,7 @@ void QuestLog::WriteCreate(ByteBuffer& data, Player const* owner, Player const* } data << int64(EndTime); data << uint32(ObjectiveFlags); + data << uint32(EnabledObjectivesMask); } void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const @@ -2138,12 +2145,16 @@ void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player cons { data << uint32(ObjectiveFlags); } + if (changesMask[5]) + { + data << uint32(EnabledObjectivesMask); + } } - if (changesMask[5]) + if (changesMask[6]) { for (uint32 i = 0; i < 24; ++i) { - if (changesMask[6 + i]) + if (changesMask[7 + i]) { data << int16(ObjectiveProgress[i]); } @@ -2157,6 +2168,7 @@ void QuestLog::ClearChangesMask() Base::ClearChangesMask(StateFlags); Base::ClearChangesMask(EndTime); Base::ClearChangesMask(ObjectiveFlags); + Base::ClearChangesMask(EnabledObjectivesMask); Base::ClearChangesMask(ObjectiveProgress); _changesMask.ResetAll(); } @@ -2302,16 +2314,25 @@ void PetCreatureName::ClearChangesMask() void CTROptions::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { - data << uint32(ConditionalFlags); + 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(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - data << uint32(ConditionalFlags); + 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 @@ -3167,7 +3188,7 @@ void BitVector::ClearChangesMask() void BitVectors::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { - for (uint32 i = 0; i < 13; ++i) + for (uint32 i = 0; i < 14; ++i) { Values[i].WriteCreate(data, owner, receiver); } @@ -3186,7 +3207,7 @@ void BitVectors::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player co data.FlushBits(); if (changesMask[0]) { - for (uint32 i = 0; i < 13; ++i) + for (uint32 i = 0; i < 14; ++i) { if (changesMask[1 + i]) { @@ -5037,6 +5058,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f 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(CharacterRestrictions.size()); data << uint32(SpellPctModByLabel.size()); data << uint32(SpellFlatModByLabel.size()); @@ -5133,6 +5158,22 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { 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 < SpellPctModByLabel.size(); ++i) { SpellPctModByLabel[i].WriteCreate(data, owner, receiver); @@ -5315,11 +5356,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data); } } - if (changesMask[42]) + if (changesMask[46]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[43]) + if (changesMask[47]) { if (!ignoreNestedChangesMask) ResearchSites[i].WriteUpdateMask(data); @@ -5328,11 +5369,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[44]) + if (changesMask[48]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[45]) + if (changesMask[49]) { if (!ignoreNestedChangesMask) ResearchSiteProgress[i].WriteUpdateMask(data); @@ -5341,11 +5382,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[46]) + if (changesMask[50]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[47]) + if (changesMask[51]) { if (!ignoreNestedChangesMask) Research[i].WriteUpdateMask(data); @@ -5354,11 +5395,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[42]) + if (changesMask[46]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[43]) + if (changesMask[47]) { for (uint32 j = 0; j < ResearchSites[i].size(); ++j) { @@ -5370,11 +5411,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[44]) + if (changesMask[48]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[45]) + if (changesMask[49]) { for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) { @@ -5386,11 +5427,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[46]) + if (changesMask[50]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[47]) + if (changesMask[51]) { for (uint32 j = 0; j < Research[i].size(); ++j) { @@ -5499,105 +5540,133 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo 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) CharacterRestrictions.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data); } - if (changesMask[25]) + if (changesMask[29]) { if (!ignoreNestedChangesMask) SpellPctModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data); } - if (changesMask[26]) + if (changesMask[30]) { if (!ignoreNestedChangesMask) SpellFlatModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data); } - if (changesMask[27]) + if (changesMask[31]) { if (!ignoreNestedChangesMask) MawPowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MawPowers.size(), data); } - if (changesMask[28]) + } + if (changesMask[32]) + { + if (changesMask[33]) { if (!ignoreNestedChangesMask) MultiFloorExploration.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.size(), data); } - if (changesMask[29]) + if (changesMask[34]) { if (!ignoreNestedChangesMask) RecipeProgression.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(RecipeProgression.size(), data); } - if (changesMask[30]) + if (changesMask[35]) { if (!ignoreNestedChangesMask) ReplayedQuests.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data); } - if (changesMask[31]) + if (changesMask[36]) { if (!ignoreNestedChangesMask) TaskQuests.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(TaskQuests.size(), data); } - } - if (changesMask[32]) - { - if (changesMask[33]) + if (changesMask[37]) { if (!ignoreNestedChangesMask) DisabledSpells.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data); } - if (changesMask[34]) + if (changesMask[38]) { if (!ignoreNestedChangesMask) CraftingOrders.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data); } - if (changesMask[35]) + if (changesMask[39]) { if (!ignoreNestedChangesMask) PersonalCraftingOrderCounts.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(PersonalCraftingOrderCounts.size(), data); } - if (changesMask[36]) + if (changesMask[40]) { if (!ignoreNestedChangesMask) NpcCraftingOrders.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(NpcCraftingOrders.size(), data); } - if (changesMask[37]) + if (changesMask[41]) { if (!ignoreNestedChangesMask) CategoryCooldownMods.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data); } - if (changesMask[38]) + if (changesMask[42]) { if (!ignoreNestedChangesMask) WeeklySpellUses.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data); } - if (changesMask[39]) + if (changesMask[43]) { if (!ignoreNestedChangesMask) TrackedCollectableSources.WriteUpdateMask(data); @@ -5768,8 +5837,48 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } + 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[29]) + { for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) { if (SpellPctModByLabel.HasChanged(i) || ignoreNestedChangesMask) @@ -5778,7 +5887,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[26]) + if (changesMask[30]) { for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) { @@ -5788,7 +5897,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[27]) + if (changesMask[31]) { for (uint32 i = 0; i < MawPowers.size(); ++i) { @@ -5798,7 +5907,10 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[28]) + } + if (changesMask[32]) + { + if (changesMask[33]) { for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) { @@ -5808,7 +5920,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[29]) + if (changesMask[34]) { for (uint32 i = 0; i < RecipeProgression.size(); ++i) { @@ -5818,7 +5930,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[30]) + if (changesMask[35]) { for (uint32 i = 0; i < ReplayedQuests.size(); ++i) { @@ -5828,7 +5940,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[31]) + if (changesMask[36]) { for (uint32 i = 0; i < TaskQuests.size(); ++i) { @@ -5838,10 +5950,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - } - if (changesMask[32]) - { - if (changesMask[33]) + if (changesMask[37]) { for (uint32 i = 0; i < DisabledSpells.size(); ++i) { @@ -5851,7 +5960,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[35]) + if (changesMask[39]) { for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) { @@ -5861,7 +5970,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[36]) + if (changesMask[40]) { for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i) { @@ -5871,7 +5980,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[37]) + if (changesMask[41]) { for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) { @@ -5881,7 +5990,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[38]) + if (changesMask[42]) { for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) { @@ -5891,7 +6000,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[39]) + if (changesMask[43]) { for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) { @@ -5905,14 +6014,14 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo data.FlushBits(); if (changesMask[32]) { - if (changesMask[40]) + if (changesMask[44]) { if (!ignoreNestedChangesMask) CharacterBankTabSettings.WriteUpdateMask(data, 3); else WriteCompleteDynamicFieldUpdateMask(CharacterBankTabSettings.size(), data, 3); } - if (changesMask[41]) + if (changesMask[45]) { if (!ignoreNestedChangesMask) AccountBankTabSettings.WriteUpdateMask(data, 3); @@ -5933,7 +6042,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[24]) + if (changesMask[28]) { for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) { @@ -5946,7 +6055,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } if (changesMask[32]) { - if (changesMask[34]) + if (changesMask[38]) { for (uint32 i = 0; i < CraftingOrders.size(); ++i) { @@ -5956,7 +6065,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[40]) + if (changesMask[44]) { for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) { @@ -5966,7 +6075,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[41]) + if (changesMask[45]) { for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) { @@ -5976,368 +6085,368 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[48]) + if (changesMask[52]) { data << *FarsightObject; } - if (changesMask[49]) + if (changesMask[53]) { data << *SummonedBattlePetGUID; } - if (changesMask[50]) + if (changesMask[54]) { data << uint64(Coinage); } - if (changesMask[51]) + if (changesMask[55]) { data << uint64(AccountBankCoinage); } - if (changesMask[52]) + if (changesMask[56]) { data << int32(XP); } - if (changesMask[53]) + if (changesMask[57]) { data << int32(NextLevelXP); } - if (changesMask[54]) + if (changesMask[58]) { data << int32(TrialXP); } - if (changesMask[55]) + if (changesMask[59]) { Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[56]) + if (changesMask[60]) { data << int32(CharacterPoints); } - if (changesMask[57]) + if (changesMask[61]) { data << int32(MaxTalentTiers); } - if (changesMask[58]) + if (changesMask[62]) { data << uint32(TrackCreatureMask); } - if (changesMask[59]) + if (changesMask[63]) { data << float(MainhandExpertise); } - if (changesMask[60]) + if (changesMask[64]) { data << float(OffhandExpertise); } - if (changesMask[61]) + if (changesMask[65]) { data << float(RangedExpertise); } - if (changesMask[62]) + if (changesMask[66]) { data << float(CombatRatingExpertise); } - if (changesMask[63]) + if (changesMask[67]) { data << float(BlockPercentage); } - if (changesMask[64]) + if (changesMask[68]) { data << float(DodgePercentage); } - if (changesMask[65]) + if (changesMask[69]) { data << float(DodgePercentageFromAttribute); } - if (changesMask[66]) + } + if (changesMask[70]) + { + if (changesMask[71]) { data << float(ParryPercentage); } - if (changesMask[67]) + if (changesMask[72]) { data << float(ParryPercentageFromAttribute); } - if (changesMask[68]) + if (changesMask[73]) { data << float(CritPercentage); } - if (changesMask[69]) + if (changesMask[74]) { data << float(RangedCritPercentage); } - } - if (changesMask[70]) - { - if (changesMask[71]) + if (changesMask[75]) { data << float(OffhandCritPercentage); } - if (changesMask[72]) + if (changesMask[76]) { data << float(SpellCritPercentage); } - if (changesMask[73]) + if (changesMask[77]) { data << int32(ShieldBlock); } - if (changesMask[74]) + if (changesMask[78]) { data << float(ShieldBlockCritPercentage); } - if (changesMask[75]) + if (changesMask[79]) { data << float(Mastery); } - if (changesMask[76]) + if (changesMask[80]) { data << float(Speed); } - if (changesMask[77]) + if (changesMask[81]) { data << float(Avoidance); } - if (changesMask[78]) + if (changesMask[82]) { data << float(Sturdiness); } - if (changesMask[79]) + if (changesMask[83]) { data << int32(Versatility); } - if (changesMask[80]) + if (changesMask[84]) { data << float(VersatilityBonus); } - if (changesMask[81]) + if (changesMask[85]) { data << float(PvpPowerDamage); } - if (changesMask[82]) + if (changesMask[86]) { data << float(PvpPowerHealing); } - if (changesMask[83]) + if (changesMask[87]) { BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[84]) + if (changesMask[88]) { data << int32(ModHealingDonePos); } - if (changesMask[85]) + if (changesMask[89]) { data << float(ModHealingPercent); } - if (changesMask[86]) + if (changesMask[90]) { data << float(ModPeriodicHealingDonePercent); } - if (changesMask[87]) + if (changesMask[91]) { data << float(ModSpellPowerPercent); } - if (changesMask[88]) + if (changesMask[92]) { data << float(ModResiliencePercent); } - if (changesMask[89]) + if (changesMask[93]) { data << float(OverrideSpellPowerByAPPercent); } - if (changesMask[90]) + if (changesMask[94]) { data << float(OverrideAPBySpellPowerPercent); } - if (changesMask[91]) + if (changesMask[95]) { data << int32(ModTargetResistance); } - if (changesMask[92]) + if (changesMask[96]) { data << int32(ModTargetPhysicalResistance); } - if (changesMask[93]) + if (changesMask[97]) { data << uint32(LocalFlags); } - if (changesMask[94]) + if (changesMask[98]) { data << uint8(GrantableLevels); } - if (changesMask[95]) + if (changesMask[99]) { data << uint8(MultiActionBars); } - if (changesMask[96]) + if (changesMask[100]) { data << uint8(LifetimeMaxRank); } - if (changesMask[97]) + if (changesMask[101]) { data << uint8(NumRespecs); } - if (changesMask[98]) + } + if (changesMask[102]) + { + if (changesMask[103]) { data << uint32(PvpMedals); } - if (changesMask[99]) + if (changesMask[104]) { data << uint16(TodayHonorableKills); } - if (changesMask[100]) + if (changesMask[105]) { data << uint16(YesterdayHonorableKills); } - if (changesMask[101]) + if (changesMask[106]) { data << uint32(LifetimeHonorableKills); } - } - if (changesMask[102]) - { - if (changesMask[103]) + if (changesMask[107]) { data << int32(WatchedFactionIndex); } - if (changesMask[104]) + if (changesMask[108]) { data << int32(MaxLevel); } - if (changesMask[105]) + if (changesMask[109]) { data << int32(ScalingPlayerLevelDelta); } - if (changesMask[106]) + if (changesMask[110]) { data << int32(MaxCreatureScalingLevel); } - if (changesMask[107]) + if (changesMask[111]) { data << int32(PetSpellPower); } - if (changesMask[108]) + if (changesMask[112]) { data << float(UiHitModifier); } - if (changesMask[109]) + if (changesMask[113]) { data << float(UiSpellHitModifier); } - if (changesMask[110]) + if (changesMask[114]) { data << int32(HomeRealmTimeOffset); } - if (changesMask[111]) + if (changesMask[115]) { data << float(ModPetHaste); } - if (changesMask[112]) + if (changesMask[116]) { data << int8(JailersTowerLevelMax); } - if (changesMask[113]) + if (changesMask[117]) { data << int8(JailersTowerLevel); } - if (changesMask[114]) + if (changesMask[118]) { data << uint8(LocalRegenFlags); } - if (changesMask[115]) + if (changesMask[119]) { data << uint8(AuraVision); } - if (changesMask[116]) + if (changesMask[120]) { data << uint8(NumBackpackSlots); } - if (changesMask[117]) + if (changesMask[121]) { data << int32(OverrideSpellsID); } - if (changesMask[118]) + if (changesMask[122]) { data << uint16(LootSpecID); } - if (changesMask[119]) + if (changesMask[123]) { data << uint32(OverrideZonePVPType); } - if (changesMask[120]) + if (changesMask[124]) { data << int32(Honor); } - if (changesMask[121]) + if (changesMask[125]) { data << int32(HonorNextLevel); } - if (changesMask[122]) + if (changesMask[126]) { data << int32(PerksProgramCurrency); } - if (changesMask[123]) + if (changesMask[127]) { data << uint8(NumBankSlots); } - if (changesMask[124]) + if (changesMask[128]) { data << uint8(NumCharacterBankTabs); } - if (changesMask[125]) + if (changesMask[129]) { data << uint8(NumAccountBankTabs); } - if (changesMask[130]) + } + if (changesMask[134]) + { + if (changesMask[135]) { data << int32(UiChromieTimeExpansionID); } - if (changesMask[131]) + if (changesMask[136]) { data << int32(TimerunningSeasonID); } - if (changesMask[132]) + if (changesMask[137]) { data << int32(TransportServerTime); } - if (changesMask[133]) + if (changesMask[138]) { data << uint32(WeeklyRewardsPeriodSinceOrigin); } - } - if (changesMask[134]) - { - if (changesMask[135]) + if (changesMask[139]) { data << int16(DEBUGSoulbindConduitRank); } - if (changesMask[138]) + if (changesMask[142]) { data << uint32(ActiveCombatTraitConfigID); } - if (changesMask[139]) + if (changesMask[143]) { data << int32(ItemUpgradeHighOnehandWeaponItemID); } - if (changesMask[140]) + if (changesMask[144]) { data << int32(ItemUpgradeHighFingerItemID); } - if (changesMask[141]) + if (changesMask[145]) { data << float(ItemUpgradeHighFingerWatermark); } - if (changesMask[142]) + if (changesMask[146]) { data << int32(ItemUpgradeHighTrinketItemID); } - if (changesMask[143]) + if (changesMask[147]) { data << float(ItemUpgradeHighTrinketWatermark); } - if (changesMask[144]) + if (changesMask[148]) { data << uint64(LootHistoryInstanceID); } - if (changesMask[146]) + if (changesMask[150]) { data << uint8(RequiredMountCapabilityFlags); } @@ -6356,58 +6465,58 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo data.FlushBits(); if (changesMask[102]) { - if (changesMask[126]) + if (changesMask[130]) { ResearchHistory->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[128]) + if (changesMask[132]) { if (QuestSession.has_value()) { QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[127]) + if (changesMask[131]) { data << *FrozenPerksVendorItem; } - if (changesMask[129]) + if (changesMask[133]) { Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } if (changesMask[134]) { - if (changesMask[136]) + if (changesMask[140]) { data << *DungeonScore; } - if (changesMask[137]) + if (changesMask[141]) { WriteMapFieldUpdate(TraitConfigs, data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[145]) + if (changesMask[149]) { if (PetStable.has_value()) { PetStable->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[147]) + if (changesMask[151]) { if (WalkInData.has_value()) { WalkInData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[148]) + if (changesMask[152]) { if (DelveData.has_value()) { DelveData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[149]) + if (changesMask[153]) { if (ChallengeModeData.has_value()) { @@ -6415,121 +6524,121 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[150]) + if (changesMask[154]) { for (uint32 i = 0; i < 105; ++i) { - if (changesMask[151 + i]) + if (changesMask[155 + i]) { data << InvSlots[i]; } } } - if (changesMask[256]) + if (changesMask[260]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[257 + i]) + if (changesMask[261 + i]) { RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[259]) + if (changesMask[263]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[260 + i]) + if (changesMask[264 + i]) { data << int32(ModDamageDonePos[i]); } - if (changesMask[267 + i]) + if (changesMask[271 + i]) { data << int32(ModDamageDoneNeg[i]); } - if (changesMask[274 + i]) + if (changesMask[278 + i]) { data << float(ModDamageDonePercent[i]); } - if (changesMask[281 + i]) + if (changesMask[285 + i]) { data << float(ModHealingDonePercent[i]); } } } - if (changesMask[288]) + if (changesMask[292]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[289 + i]) + if (changesMask[293 + i]) { data << float(WeaponDmgMultipliers[i]); } - if (changesMask[292 + i]) + if (changesMask[296 + i]) { data << float(WeaponAtkSpeedMultipliers[i]); } } } - if (changesMask[295]) + if (changesMask[299]) { for (uint32 i = 0; i < 12; ++i) { - if (changesMask[296 + i]) + if (changesMask[300 + i]) { data << uint32(BuybackPrice[i]); } - if (changesMask[308 + i]) + if (changesMask[312 + i]) { data << int64(BuybackTimestamp[i]); } } } - if (changesMask[320]) + if (changesMask[324]) { for (uint32 i = 0; i < 32; ++i) { - if (changesMask[321 + i]) + if (changesMask[325 + i]) { data << int32(CombatRatings[i]); } } } - if (changesMask[353]) + if (changesMask[357]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[354 + i]) + if (changesMask[358 + i]) { data << uint32(NoReagentCostMask[i]); } } } - if (changesMask[358]) + if (changesMask[362]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[359 + i]) + if (changesMask[363 + i]) { data << int32(ProfessionSkillLine[i]); } } } - if (changesMask[361]) + if (changesMask[365]) { for (uint32 i = 0; i < 5; ++i) { - if (changesMask[362 + i]) + if (changesMask[366 + i]) { data << uint32(BagSlotFlags[i]); } } } - if (changesMask[367]) + if (changesMask[371]) { for (uint32 i = 0; i < 17; ++i) { - if (changesMask[368 + i]) + if (changesMask[372 + i]) { data << float(ItemUpgradeHighWatermark[i]); } @@ -6565,6 +6674,10 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(RuneforgePowers); Base::ClearChangesMask(TransmogIllusions); Base::ClearChangesMask(WarbandScenes); + Base::ClearChangesMask(HouseRooms); + Base::ClearChangesMask(HouseExteriorComponents); + Base::ClearChangesMask(HouseThemes); + Base::ClearChangesMask(HouseRoomComponentTextures); Base::ClearChangesMask(SpellPctModByLabel); Base::ClearChangesMask(SpellFlatModByLabel); Base::ClearChangesMask(MawPowers); @@ -8365,6 +8478,86 @@ void ConversationData::ClearChangesMask() _changesMask.ResetAll(); } +void AaBox::WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const +{ + data << Low; + data << High; +} + +void AaBox::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const +{ + data << Low; + data << High; +} + +bool AaBox::operator==(AaBox const& right) const +{ + return Low == right.Low + && High == right.High; +} + +void MeshObjectData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + data.WriteBit(IsWMO); + data.WriteBit(IsRoom); + data.WriteBits(Geobox.has_value(), 1); + data << int32(FileDataID); + if (Geobox.has_value()) + { + Geobox->WriteCreate(data, owner, receiver); + } + data.FlushBits(); + data.FlushBits(); +} + +void MeshObjectData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void MeshObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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()) + { + Geobox->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + data.FlushBits(); +} + +void MeshObjectData::ClearChangesMask() +{ + Base::ClearChangesMask(IsWMO); + Base::ClearChangesMask(IsRoom); + Base::ClearChangesMask(FileDataID); + Base::ClearChangesMask(Geobox); + _changesMask.ResetAll(); +} + void VendorData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Creature const* owner, Player const* receiver) const { data << int32(Flags); @@ -8395,6 +8588,1127 @@ void VendorData::ClearChangesMask() _changesMask.ResetAll(); } +void DecorStoragePersistedDataDyes::WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const +{ + for (uint32 i = 0; i < 3; ++i) + { + data << int32(DyeColorID[i]); + } +} + +void DecorStoragePersistedDataDyes::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const +{ + for (uint32 i = 0; i < 3; ++i) + { + data << int32(DyeColorID[i]); + } +} + +bool DecorStoragePersistedDataDyes::operator==(DecorStoragePersistedDataDyes const& right) const +{ + return std::ranges::equal(DyeColorID, right.DyeColorID); +} + +void DecorStoragePersistedData::WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const +{ + data << *HouseGUID; + data << uint8(Field_20); + data.WriteBits(Dyes.has_value(), 1); + if (Dyes.has_value()) + { + Dyes->WriteCreate(data, owner, receiver); + } +} + +void DecorStoragePersistedData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *HouseGUID; + } + if (changesMask[3]) + { + data << uint8(Field_20); + } + data.WriteBits(Dyes.has_value(), 1); + if (changesMask[2]) + { + if (Dyes.has_value()) + { + Dyes->WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } +} + +void DecorStoragePersistedData::ClearChangesMask() +{ + Base::ClearChangesMask(HouseGUID); + Base::ClearChangesMask(Dyes); + Base::ClearChangesMask(Field_20); + _changesMask.ResetAll(); +} + +void HousingDecorData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + data << *DecorGUID; + data << *AttachParentGUID; + data << uint8(Flags); + data << *Field_68; + data.WriteBits(PersistedData.has_value(), 1); + if (PersistedData.has_value()) + { + PersistedData->WriteCreate(data, owner, receiver); + } +} + +void HousingDecorData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingDecorData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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 << *Field_68; + } + data.WriteBits(PersistedData.has_value(), 1); + if (changesMask[4]) + { + if (PersistedData.has_value()) + { + PersistedData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } +} + +void HousingDecorData::ClearChangesMask() +{ + Base::ClearChangesMask(DecorGUID); + Base::ClearChangesMask(AttachParentGUID); + Base::ClearChangesMask(Flags); + Base::ClearChangesMask(PersistedData); + Base::ClearChangesMask(Field_68); + _changesMask.ResetAll(); +} + +void HousingDoorData::WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const +{ + data << int32(RoomComponentID); + data << *RoomComponentOffset; + data << uint8(RoomComponentType); + data << *AttachedRoomGUID; +} + +void HousingDoorData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) 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, owner, receiver); + } +} + +void HousingRoomData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingRoomData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingRoomComponentMeshData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + data << *BnetAccount; + data << int32(PlotIndex); + data << uint32(Level); + data << uint64(Field_20); + data << uint32(InteriorDecorPlacementBudget); + data << uint32(ExteriorDecorPlacementBudget); + data << uint32(ExteriorFixtureBudget); + data << uint32(RoomPlacementBudget); + data << *EntityGUID; +} + +void HousingPlayerHouseData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingPlayerHouseData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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(Field_20); + } + if (changesMask[5]) + { + data << uint32(InteriorDecorPlacementBudget); + } + if (changesMask[6]) + { + data << uint32(ExteriorDecorPlacementBudget); + } + if (changesMask[7]) + { + data << uint32(ExteriorFixtureBudget); + } + if (changesMask[8]) + { + data << uint32(RoomPlacementBudget); + } + if (changesMask[9]) + { + data << *EntityGUID; + } + } +} + +void HousingPlayerHouseData::ClearChangesMask() +{ + Base::ClearChangesMask(BnetAccount); + Base::ClearChangesMask(PlotIndex); + Base::ClearChangesMask(Level); + Base::ClearChangesMask(Field_20); + Base::ClearChangesMask(InteriorDecorPlacementBudget); + Base::ClearChangesMask(ExteriorDecorPlacementBudget); + Base::ClearChangesMask(ExteriorFixtureBudget); + Base::ClearChangesMask(RoomPlacementBudget); + Base::ClearChangesMask(EntityGUID); + _changesMask.ResetAll(); +} + +void HousingCornerstoneData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const +{ + data << uint64(Cost); + data << int32(PlotIndex); +} + +void HousingCornerstoneData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingCornerstoneData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const +{ + data << uint32(Field_0); + data << *HouseOwnerGUID; + data << *HouseGUID; + data << *HouseOwnerBnetAccountGUID; +} + +void HousingPlotAreaTriggerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingPlotAreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + data.WriteBits(changesMask.GetBlock(0), 5); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(Field_0); + } + if (changesMask[2]) + { + data << *HouseOwnerGUID; + } + if (changesMask[3]) + { + data << *HouseGUID; + } + if (changesMask[4]) + { + data << *HouseOwnerBnetAccountGUID; + } + } +} + +void HousingPlotAreaTriggerData::ClearChangesMask() +{ + Base::ClearChangesMask(Field_0); + Base::ClearChangesMask(HouseOwnerGUID); + Base::ClearChangesMask(HouseGUID); + Base::ClearChangesMask(HouseOwnerBnetAccountGUID); + _changesMask.ResetAll(); +} + +void PlayerHouseInfo::WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const +{ + data << HouseGUID; + data << OwnerGUID; +} + +void PlayerHouseInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const +{ + data << HouseGUID; + data << OwnerGUID; +} + +bool PlayerHouseInfo::operator==(PlayerHouseInfo const& right) const +{ + return HouseGUID == right.HouseGUID + && OwnerGUID == right.OwnerGUID; +} + +void HousingOwner::WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const +{ + data << BnetAccountGUID; + data << PlayerGUID; +} + +void HousingOwner::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const +{ + data << BnetAccountGUID; + data << PlayerGUID; +} + +bool HousingOwner::operator==(HousingOwner const& right) const +{ + return BnetAccountGUID == right.BnetAccountGUID + && PlayerGUID == right.PlayerGUID; +} + +void NeighborhoodMirrorData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) 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, owner, receiver); + } + for (uint32 i = 0; i < Managers.size(); ++i) + { + Managers[i].WriteCreate(data, owner, receiver); + } +} + +void NeighborhoodMirrorData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void NeighborhoodMirrorData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < Managers.size(); ++i) + { + if (Managers.HasChanged(i) || ignoreNestedChangesMask) + { + Managers[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + } + 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, Object const* owner, Player const* receiver) 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(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + PositionData->WriteCreate(data, owner, receiver); +} + +void MirroredPositionData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void MirroredPositionData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const +{ + data.WriteBits(changesMask.GetBlock(0), 2); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + PositionData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } +} + +void MirroredPositionData::ClearChangesMask() +{ + Base::ClearChangesMask(PositionData); + _changesMask.ResetAll(); +} + +void PlayerMirrorHouse::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << Guid; + data << NeighborhoodGUID; + data << uint32(Level); + data << uint32(Favor); + data << int32(Field_28); +} + +void PlayerMirrorHouse::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + data << Guid; + data << NeighborhoodGUID; + data << uint32(Level); + data << uint32(Favor); + data << int32(Field_28); +} + +bool PlayerMirrorHouse::operator==(PlayerMirrorHouse const& right) const +{ + return Guid == right.Guid + && NeighborhoodGUID == right.NeighborhoodGUID + && Level == right.Level + && Favor == right.Favor + && Field_28 == right.Field_28; +} + +void NeighborhoodCharterSignature::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << Guid; +} + +void NeighborhoodCharterSignature::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + data << Guid; +} + +bool NeighborhoodCharterSignature::operator==(NeighborhoodCharterSignature const& right) const +{ + return Guid == right.Guid; +} + +void NeighborhoodCharter::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) 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, owner, receiver); + } + data.WriteBits(Name.size() + 1, 8); + data << WorldPackets::SizedCString::Data(Name); +} + +void NeighborhoodCharter::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + data << int32(Field_0); + data << int32(Field_4); + data << uint32(Signatures.size()); + for (uint32 i = 0; i < Signatures.size(); ++i) + { + Signatures[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + 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 PlayerHouseInfoComponentData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const +{ + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + { + data << uint32(Field_8.size()); + data << *Field_40; + } + 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(Field_178); + 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, owner, receiver); + } + 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, owner, receiver); + } +} + +static constexpr void PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(PlayerHouseInfoComponentData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) +{ + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + allowedMaskForTarget |= std::array<uint32, 1>{ 0x000001FAu }; +} + +void PlayerHouseInfoComponentData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) +{ + PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); +} + +void PlayerHouseInfoComponentData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) +{ + Mask allowedMaskForTarget({ 0x00000005u }); + PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + changesMask &= allowedMaskForTarget; +} + +void PlayerHouseInfoComponentData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const +{ + Mask allowedMaskForTarget({ 0x00000005u }); + PlayerHouseInfoComponentDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); +} + +void PlayerHouseInfoComponentData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) 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(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + 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[6]) + { + data << *Field_40; + } + if (changesMask[8]) + { + data << uint8(Field_178); + } + if (changesMask[7]) + { + Charter->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } +} + +void PlayerHouseInfoComponentData::ClearChangesMask() +{ + Base::ClearChangesMask(Field_8); + Base::ClearChangesMask(Houses); + Base::ClearChangesMask(Field_88); + Base::ClearChangesMask(Field_C0); + Base::ClearChangesMask(Field_F8); + Base::ClearChangesMask(Field_40); + Base::ClearChangesMask(Charter); + Base::ClearChangesMask(Field_178); + _changesMask.ResetAll(); +} + +void HousingStorageData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteMapFieldCreate(Decor, data, owner, receiver); + data << uint32(DecorMaxOwnedCount); +} + +void HousingStorageData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingStorageData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const +{ + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + WriteMapFieldUpdate(Decor, data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[2]) + { + data << uint32(DecorMaxOwnedCount); + } + } +} + +void HousingStorageData::ClearChangesMask() +{ + Base::ClearChangesMask(Decor); + Base::ClearChangesMask(DecorMaxOwnedCount); + _changesMask.ResetAll(); +} + +void HousingFixtureData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) 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(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const +{ + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void HousingFixtureData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) 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(); +} + } #if TRINITY_COMPILER == TRINITY_COMPILER_GNU diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index aad04046fb0..1ccb5e0fdd7 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -271,7 +271,7 @@ struct UnitAssistActionData : public IsUpdateFieldStructureTag, public HasChange void ClearChangesMask(); }; -struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<223> +struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<224> { UpdateField<bool, 0, 1> Field_314; UpdateField<std::vector<uint32>, 0, 2> StateWorldEffectIDs; @@ -312,127 +312,128 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<223> UpdateField<uint8, 0, 29> ClassId; UpdateField<uint8, 0, 30> PlayerClassId; UpdateField<uint8, 0, 31> Sex; - UpdateField<uint8, 32, 33> DisplayPower; - UpdateField<uint32, 32, 34> OverrideDisplayPowerID; - UpdateField<int64, 32, 35> Health; - UpdateField<int64, 32, 36> MaxHealth; - UpdateField<int32, 32, 37> Level; - UpdateField<int32, 32, 38> EffectiveLevel; - UpdateField<int32, 32, 39> ContentTuningID; - UpdateField<int32, 32, 40> ScalingLevelMin; - UpdateField<int32, 32, 41> ScalingLevelMax; - UpdateField<int32, 32, 42> ScalingLevelDelta; - UpdateField<uint8, 32, 43> ScalingFactionGroup; - UpdateField<int32, 32, 44> FactionTemplate; + UpdateField<uint8, 32, 33> CreatureType; + UpdateField<uint8, 32, 34> DisplayPower; + UpdateField<uint32, 32, 35> OverrideDisplayPowerID; + UpdateField<int64, 32, 36> Health; + UpdateField<int64, 32, 37> MaxHealth; + UpdateField<int32, 32, 38> Level; + UpdateField<int32, 32, 39> EffectiveLevel; + UpdateField<int32, 32, 40> ContentTuningID; + UpdateField<int32, 32, 41> ScalingLevelMin; + UpdateField<int32, 32, 42> ScalingLevelMax; + UpdateField<int32, 32, 43> ScalingLevelDelta; + UpdateField<uint8, 32, 44> ScalingFactionGroup; + UpdateField<int32, 32, 45> FactionTemplate; struct FactionTemplateTag : ViewerDependentValueTag<int32> {}; - UpdateField<uint32, 32, 45> Flags; + UpdateField<uint32, 32, 46> Flags; struct FlagsTag : ViewerDependentValueTag<uint32> {}; - UpdateField<uint32, 32, 46> Flags2; + UpdateField<uint32, 32, 47> Flags2; struct Flags2Tag : ViewerDependentValueTag<uint32> {}; - UpdateField<uint32, 32, 47> Flags3; + UpdateField<uint32, 32, 48> Flags3; struct Flags3Tag : ViewerDependentValueTag<uint32> {}; - UpdateField<uint32, 32, 48> Flags4; + UpdateField<uint32, 32, 49> Flags4; struct Flags4Tag : ViewerDependentValueTag<uint32> {}; - UpdateField<uint32, 32, 49> AuraState; + UpdateField<uint32, 32, 50> AuraState; struct AuraStateTag : ViewerDependentValueTag<uint32> {}; - UpdateField<uint32, 32, 50> RangedAttackRoundBaseTime; - UpdateField<float, 32, 51> BoundingRadius; - UpdateField<float, 32, 52> CombatReach; - UpdateField<float, 32, 53> DisplayScale; - UpdateField<int32, 32, 54> CreatureFamily; - UpdateField<uint8, 32, 55> CreatureType; - UpdateField<int32, 32, 56> NativeDisplayID; - UpdateField<float, 32, 57> NativeXDisplayScale; - UpdateField<int32, 32, 58> MountDisplayID; - UpdateField<int32, 32, 59> CosmeticMountDisplayID; - UpdateField<float, 32, 60> MinDamage; - UpdateField<float, 32, 61> MaxDamage; - UpdateField<float, 32, 62> MinOffHandDamage; - UpdateField<float, 32, 63> MaxOffHandDamage; - UpdateField<uint8, 64, 65> StandState; - UpdateField<uint8, 64, 66> PetTalentPoints; - UpdateField<uint8, 64, 67> VisFlags; - UpdateField<uint8, 64, 68> AnimTier; - UpdateField<uint32, 64, 69> PetNumber; - UpdateField<uint32, 64, 70> PetNameTimestamp; - UpdateField<uint32, 64, 71> PetExperience; - UpdateField<uint32, 64, 72> PetNextLevelExperience; - UpdateField<float, 64, 73> ModCastingSpeed; - UpdateField<float, 64, 74> ModCastingSpeedNeg; - UpdateField<float, 64, 75> ModSpellHaste; - UpdateField<float, 64, 76> ModHaste; - UpdateField<float, 64, 77> ModRangedHaste; - UpdateField<float, 64, 78> ModHasteRegen; - UpdateField<float, 64, 79> ModTimeRate; - UpdateField<int32, 64, 80> CreatedBySpell; - UpdateField<int32, 64, 81> EmoteState; - UpdateField<int32, 64, 82> BaseMana; - UpdateField<int32, 64, 83> BaseHealth; - UpdateField<uint8, 64, 84> SheatheState; - UpdateField<uint8, 64, 85> PvpFlags; + UpdateField<uint32, 32, 51> RangedAttackRoundBaseTime; + UpdateField<float, 32, 52> BoundingRadius; + UpdateField<float, 32, 53> CombatReach; + UpdateField<float, 32, 54> DisplayScale; + UpdateField<int32, 32, 55> CreatureFamily; + UpdateField<uint8, 32, 56> OverrideCreatureType; + UpdateField<int32, 32, 57> NativeDisplayID; + UpdateField<float, 32, 58> NativeXDisplayScale; + UpdateField<int32, 32, 59> MountDisplayID; + UpdateField<int32, 32, 60> CosmeticMountDisplayID; + UpdateField<float, 32, 61> MinDamage; + UpdateField<float, 32, 62> MaxDamage; + UpdateField<float, 32, 63> MinOffHandDamage; + UpdateField<float, 64, 65> MaxOffHandDamage; + UpdateField<uint8, 64, 66> StandState; + UpdateField<uint8, 64, 67> PetTalentPoints; + UpdateField<uint8, 64, 68> VisFlags; + UpdateField<uint8, 64, 69> AnimTier; + UpdateField<uint32, 64, 70> PetNumber; + UpdateField<uint32, 64, 71> PetNameTimestamp; + UpdateField<uint32, 64, 72> PetExperience; + UpdateField<uint32, 64, 73> PetNextLevelExperience; + UpdateField<float, 64, 74> ModCastingSpeed; + UpdateField<float, 64, 75> ModCastingSpeedNeg; + UpdateField<float, 64, 76> ModSpellHaste; + UpdateField<float, 64, 77> ModHaste; + UpdateField<float, 64, 78> ModRangedHaste; + UpdateField<float, 64, 79> ModHasteRegen; + UpdateField<float, 64, 80> ModTimeRate; + UpdateField<int32, 64, 81> CreatedBySpell; + UpdateField<int32, 64, 82> EmoteState; + UpdateField<int32, 64, 83> BaseMana; + UpdateField<int32, 64, 84> BaseHealth; + UpdateField<uint8, 64, 85> SheatheState; + UpdateField<uint8, 64, 86> PvpFlags; struct PvpFlagsTag : ViewerDependentValueTag<uint8> {}; - UpdateField<uint8, 64, 86> PetFlags; - UpdateField<uint8, 64, 87> ShapeshiftForm; - UpdateField<int32, 64, 88> AttackPower; - UpdateField<int32, 64, 89> AttackPowerModPos; - UpdateField<int32, 64, 90> AttackPowerModNeg; - UpdateField<float, 64, 91> AttackPowerMultiplier; - UpdateField<int32, 64, 92> AttackPowerModSupport; - UpdateField<int32, 64, 93> RangedAttackPower; - UpdateField<int32, 64, 94> RangedAttackPowerModPos; - UpdateField<int32, 64, 95> RangedAttackPowerModNeg; - UpdateField<float, 96, 97> RangedAttackPowerMultiplier; - UpdateField<int32, 96, 98> RangedAttackPowerModSupport; - UpdateField<int32, 96, 99> MainHandWeaponAttackPower; - UpdateField<int32, 96, 100> OffHandWeaponAttackPower; - UpdateField<int32, 96, 101> RangedWeaponAttackPower; - UpdateField<int32, 96, 102> SetAttackSpeedAura; - UpdateField<float, 96, 103> Lifesteal; - UpdateField<float, 96, 104> MinRangedDamage; - UpdateField<float, 96, 105> MaxRangedDamage; - UpdateField<float, 96, 106> ManaCostMultiplier; - UpdateField<float, 96, 107> MaxHealthModifier; - UpdateField<float, 96, 108> HoverHeight; - UpdateField<int32, 96, 109> MinItemLevelCutoff; - UpdateField<int32, 96, 110> MinItemLevel; - UpdateField<int32, 96, 111> MaxItemLevel; - UpdateField<int32, 96, 112> AzeriteItemLevel; - UpdateField<int32, 96, 113> WildBattlePetLevel; - UpdateField<int32, 96, 114> BattlePetCompanionExperience; - UpdateField<uint32, 96, 115> BattlePetCompanionNameTimestamp; - UpdateField<int32, 96, 116> InteractSpellID; + UpdateField<uint8, 64, 87> PetFlags; + UpdateField<uint8, 64, 88> ShapeshiftForm; + UpdateField<int32, 64, 89> AttackPower; + UpdateField<int32, 64, 90> AttackPowerModPos; + UpdateField<int32, 64, 91> AttackPowerModNeg; + UpdateField<float, 64, 92> AttackPowerMultiplier; + UpdateField<int32, 64, 93> AttackPowerModSupport; + UpdateField<int32, 64, 94> RangedAttackPower; + UpdateField<int32, 64, 95> RangedAttackPowerModPos; + UpdateField<int32, 96, 97> RangedAttackPowerModNeg; + UpdateField<float, 96, 98> RangedAttackPowerMultiplier; + UpdateField<int32, 96, 99> RangedAttackPowerModSupport; + UpdateField<int32, 96, 100> MainHandWeaponAttackPower; + UpdateField<int32, 96, 101> OffHandWeaponAttackPower; + UpdateField<int32, 96, 102> RangedWeaponAttackPower; + UpdateField<int32, 96, 103> SetAttackSpeedAura; + UpdateField<float, 96, 104> Lifesteal; + UpdateField<float, 96, 105> MinRangedDamage; + UpdateField<float, 96, 106> MaxRangedDamage; + UpdateField<float, 96, 107> ManaCostMultiplier; + UpdateField<float, 96, 108> MaxHealthModifier; + UpdateField<float, 96, 109> HoverHeight; + UpdateField<int32, 96, 110> MinItemLevelCutoff; + UpdateField<int32, 96, 111> MinItemLevel; + UpdateField<int32, 96, 112> MaxItemLevel; + UpdateField<int32, 96, 113> AzeriteItemLevel; + UpdateField<int32, 96, 114> WildBattlePetLevel; + UpdateField<int32, 96, 115> BattlePetCompanionExperience; + UpdateField<uint32, 96, 116> BattlePetCompanionNameTimestamp; + UpdateField<int32, 96, 117> InteractSpellID; struct InteractSpellIDTag : ViewerDependentValueTag<int32> {}; - UpdateField<int32, 96, 117> ScaleDuration; - UpdateField<int32, 96, 118> LooksLikeMountID; - UpdateField<int32, 96, 119> LooksLikeCreatureID; - UpdateField<int32, 96, 120> LookAtControllerID; - UpdateField<int32, 96, 121> PerksVendorItemID; - UpdateField<int32, 96, 122> TaxiNodesID; - UpdateField<ObjectGuid, 96, 123> GuildGUID; - UpdateField<int32, 96, 124> FlightCapabilityID; - UpdateField<float, 96, 125> GlideEventSpeedDivisor; // Movement speed gets divided by this value when evaluating what GlideEvents to use - UpdateField<int32, 96, 126> DriveCapabilityID; - UpdateField<int32, 96, 127> MaxHealthModifierFlatNeg; - UpdateField<int32, 128, 129> MaxHealthModifierFlatPos; - UpdateField<uint32, 128, 130> SilencedSchoolMask; - UpdateField<uint32, 128, 131> CurrentAreaID; - UpdateField<float, 128, 132> Field_31C; - UpdateField<float, 128, 133> Field_320; // Soft targeting related? When UnitFlags3 & 0x40000000 is set, increases some range check using CombatReach by this amount - UpdateField<ObjectGuid, 128, 134> NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object - OptionalUpdateField<UF::UnitAssistActionData, 128, 135> AssistActionData; - UpdateFieldArray<int32, 10, 136, 137> Power; - UpdateFieldArray<int32, 10, 136, 147> MaxPower; - UpdateFieldArray<float, 10, 136, 157> PowerRegenFlatModifier; - UpdateFieldArray<float, 10, 136, 167> PowerRegenInterruptedFlatModifier; - UpdateFieldArray<UF::VisibleItem, 3, 177, 178> VirtualItems; - UpdateFieldArray<uint32, 2, 181, 182> AttackRoundBaseTime; - UpdateFieldArray<int32, 4, 184, 185> Stats; - UpdateFieldArray<int32, 4, 184, 189> StatPosBuff; - UpdateFieldArray<int32, 4, 184, 193> StatNegBuff; - UpdateFieldArray<int32, 4, 184, 197> StatSupportBuff; - UpdateFieldArray<int32, 7, 201, 202> Resistances; - UpdateFieldArray<int32, 7, 201, 209> BonusResistanceMods; - UpdateFieldArray<int32, 7, 201, 216> ManaCostModifier; + UpdateField<int32, 96, 118> ScaleDuration; + UpdateField<int32, 96, 119> LooksLikeMountID; + UpdateField<int32, 96, 120> LooksLikeCreatureID; + UpdateField<int32, 96, 121> LookAtControllerID; + UpdateField<int32, 96, 122> PerksVendorItemID; + UpdateField<int32, 96, 123> TaxiNodesID; + UpdateField<ObjectGuid, 96, 124> GuildGUID; + UpdateField<int32, 96, 125> FlightCapabilityID; + UpdateField<float, 96, 126> GlideEventSpeedDivisor; // Movement speed gets divided by this value when evaluating what GlideEvents to use + UpdateField<int32, 96, 127> DriveCapabilityID; + UpdateField<int32, 128, 129> MaxHealthModifierFlatNeg; + UpdateField<int32, 128, 130> MaxHealthModifierFlatPos; + UpdateField<uint32, 128, 131> SilencedSchoolMask; + UpdateField<uint32, 128, 132> CurrentAreaID; + UpdateField<float, 128, 133> Field_31C; + UpdateField<float, 128, 134> Field_320; // Soft targeting related? When UnitFlags3 & 0x40000000 is set, increases some range check using CombatReach by this amount + UpdateField<ObjectGuid, 128, 135> NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object + OptionalUpdateField<UF::UnitAssistActionData, 128, 136> AssistActionData; + UpdateFieldArray<int32, 10, 137, 138> Power; + UpdateFieldArray<int32, 10, 137, 148> MaxPower; + UpdateFieldArray<float, 10, 137, 158> PowerRegenFlatModifier; + UpdateFieldArray<float, 10, 137, 168> PowerRegenInterruptedFlatModifier; + UpdateFieldArray<UF::VisibleItem, 3, 178, 179> VirtualItems; + UpdateFieldArray<uint32, 2, 182, 183> AttackRoundBaseTime; + UpdateFieldArray<int32, 4, 185, 186> Stats; + UpdateFieldArray<int32, 4, 185, 190> StatPosBuff; + UpdateFieldArray<int32, 4, 185, 194> StatNegBuff; + UpdateFieldArray<int32, 4, 185, 198> StatSupportBuff; + UpdateFieldArray<int32, 7, 202, 203> Resistances; + UpdateFieldArray<int32, 7, 202, 210> BonusResistanceMods; + UpdateFieldArray<int32, 7, 202, 217> ManaCostModifier; void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; @@ -453,13 +454,14 @@ struct ChrCustomizationChoice : public IsUpdateFieldStructureTag bool operator!=(ChrCustomizationChoice const& right) const { return !(*this == right); } }; -struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<30> +struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<31> { UpdateField<int32, 0, 1> QuestID; UpdateField<uint16, 0, 2> StateFlags; UpdateField<int64, 0, 3> EndTime; UpdateField<uint32, 0, 4> ObjectiveFlags; - UpdateFieldArray<int16, 24, 5, 6> ObjectiveProgress; + UpdateField<uint32, 0, 5> EnabledObjectivesMask; + UpdateFieldArray<int16, 24, 6, 7> ObjectiveProgress; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; @@ -503,7 +505,7 @@ struct PetCreatureName : public IsUpdateFieldStructureTag, public HasChangesMask struct CTROptions : public IsUpdateFieldStructureTag { - uint32 ConditionalFlags; + std::vector<uint32> ConditionalFlags; uint8 FactionGroup; uint32 ChromieTimeExpansionMask; @@ -643,9 +645,9 @@ struct BitVector : public IsUpdateFieldStructureTag, public HasChangesMask<2> void ClearChangesMask(); }; -struct BitVectors : public IsUpdateFieldStructureTag, public HasChangesMask<14> +struct BitVectors : public IsUpdateFieldStructureTag, public HasChangesMask<15> { - UpdateFieldArray<UF::BitVector, 13, 0, 1> Values; + UpdateFieldArray<UF::BitVector, 14, 0, 1> Values; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; @@ -1091,7 +1093,7 @@ struct Research : public IsUpdateFieldStructureTag bool operator!=(Research const& right) const { return !(*this == right); } }; -struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<385> +struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<389> { UpdateField<bool, 0, 1> BackpackAutoSortDisabled; UpdateField<bool, 0, 2> BackpackSellJunkDisabled; @@ -1099,9 +1101,9 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas UpdateField<bool, 0, 4> SortBagsRightToLeft; UpdateField<bool, 0, 5> InsertItemsLeftToRight; UpdateField<bool, 0, 6> HasPerksProgramPendingReward; - UpdateFieldArray<DynamicUpdateFieldBase<uint16>, 1, 42, 43> ResearchSites; - UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 44, 45> ResearchSiteProgress; - UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 46, 47> Research; + UpdateFieldArray<DynamicUpdateFieldBase<uint16>, 1, 46, 47> ResearchSites; + UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 48, 49> ResearchSiteProgress; + UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 50, 51> Research; DynamicUpdateField<uint64, 0, 7> KnownTitles; DynamicUpdateField<UF::PlayerDataElement, 0, 8> CharacterDataElements; DynamicUpdateField<UF::PlayerDataElement, 0, 9> AccountDataElements; @@ -1118,138 +1120,142 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas DynamicUpdateField<uint32, 0, 21> RuneforgePowers; DynamicUpdateField<uint32, 0, 22> TransmogIllusions; DynamicUpdateField<uint32, 0, 23> WarbandScenes; - DynamicUpdateField<UF::SpellPctModByLabel, 0, 25> SpellPctModByLabel; - DynamicUpdateField<UF::SpellFlatModByLabel, 0, 26> SpellFlatModByLabel; - DynamicUpdateField<UF::MawPower, 0, 27> MawPowers; - DynamicUpdateField<UF::MultiFloorExplore, 0, 28> MultiFloorExploration; - DynamicUpdateField<UF::RecipeProgressionInfo, 0, 29> RecipeProgression; - DynamicUpdateField<UF::ReplayedQuest, 0, 30> ReplayedQuests; - DynamicUpdateField<UF::QuestLog, 0, 31> TaskQuests; - DynamicUpdateField<int32, 32, 33> DisabledSpells; - DynamicUpdateField<UF::PersonalCraftingOrderCount, 32, 35> PersonalCraftingOrderCounts; - DynamicUpdateField<UF::NPCCraftingOrderInfo, 32, 36> NpcCraftingOrders; - DynamicUpdateField<UF::CategoryCooldownMod, 32, 37> CategoryCooldownMods; - DynamicUpdateField<UF::WeeklySpellUse, 32, 38> WeeklySpellUses; - DynamicUpdateField<UF::CollectableSourceTrackedData, 32, 39> TrackedCollectableSources; + DynamicUpdateField<uint32, 0, 24> HouseRooms; + DynamicUpdateField<uint32, 0, 25> HouseExteriorComponents; + DynamicUpdateField<uint32, 0, 26> HouseThemes; + DynamicUpdateField<uint32, 0, 27> HouseRoomComponentTextures; + DynamicUpdateField<UF::SpellPctModByLabel, 0, 29> SpellPctModByLabel; + DynamicUpdateField<UF::SpellFlatModByLabel, 0, 30> SpellFlatModByLabel; + DynamicUpdateField<UF::MawPower, 0, 31> MawPowers; + DynamicUpdateField<UF::MultiFloorExplore, 32, 33> MultiFloorExploration; + DynamicUpdateField<UF::RecipeProgressionInfo, 32, 34> RecipeProgression; + DynamicUpdateField<UF::ReplayedQuest, 32, 35> ReplayedQuests; + DynamicUpdateField<UF::QuestLog, 32, 36> TaskQuests; + DynamicUpdateField<int32, 32, 37> DisabledSpells; + DynamicUpdateField<UF::PersonalCraftingOrderCount, 32, 39> PersonalCraftingOrderCounts; + DynamicUpdateField<UF::NPCCraftingOrderInfo, 32, 40> NpcCraftingOrders; + DynamicUpdateField<UF::CategoryCooldownMod, 32, 41> CategoryCooldownMods; + DynamicUpdateField<UF::WeeklySpellUse, 32, 42> WeeklySpellUses; + DynamicUpdateField<UF::CollectableSourceTrackedData, 32, 43> TrackedCollectableSources; DynamicUpdateField<UF::PVPInfo, 0, 10> PvpInfo; - DynamicUpdateField<UF::CharacterRestriction, 0, 24> CharacterRestrictions; - DynamicUpdateField<UF::CraftingOrder, 32, 34> CraftingOrders; - DynamicUpdateField<UF::BankTabSettings, 32, 40> CharacterBankTabSettings; - DynamicUpdateField<UF::BankTabSettings, 32, 41> AccountBankTabSettings; - UpdateField<ObjectGuid, 32, 48> FarsightObject; - UpdateField<ObjectGuid, 32, 49> SummonedBattlePetGUID; - UpdateField<uint64, 32, 50> Coinage; - UpdateField<uint64, 32, 51> AccountBankCoinage; - UpdateField<int32, 32, 52> XP; - UpdateField<int32, 32, 53> NextLevelXP; - UpdateField<int32, 32, 54> TrialXP; - UpdateField<UF::SkillInfo, 32, 55> Skill; - UpdateField<int32, 32, 56> CharacterPoints; - UpdateField<int32, 32, 57> MaxTalentTiers; - UpdateField<uint32, 32, 58> TrackCreatureMask; - UpdateField<float, 32, 59> MainhandExpertise; - UpdateField<float, 32, 60> OffhandExpertise; - UpdateField<float, 32, 61> RangedExpertise; - UpdateField<float, 32, 62> CombatRatingExpertise; - UpdateField<float, 32, 63> BlockPercentage; - UpdateField<float, 32, 64> DodgePercentage; - UpdateField<float, 32, 65> DodgePercentageFromAttribute; - UpdateField<float, 32, 66> ParryPercentage; - UpdateField<float, 32, 67> ParryPercentageFromAttribute; - UpdateField<float, 32, 68> CritPercentage; - UpdateField<float, 32, 69> RangedCritPercentage; - UpdateField<float, 70, 71> OffhandCritPercentage; - UpdateField<float, 70, 72> SpellCritPercentage; - UpdateField<int32, 70, 73> ShieldBlock; - UpdateField<float, 70, 74> ShieldBlockCritPercentage; - UpdateField<float, 70, 75> Mastery; - UpdateField<float, 70, 76> Speed; - UpdateField<float, 70, 77> Avoidance; - UpdateField<float, 70, 78> Sturdiness; - UpdateField<int32, 70, 79> Versatility; - UpdateField<float, 70, 80> VersatilityBonus; - UpdateField<float, 70, 81> PvpPowerDamage; - UpdateField<float, 70, 82> PvpPowerHealing; - UpdateField<UF::BitVectors, 70, 83> BitVectors; - UpdateField<int32, 70, 84> ModHealingDonePos; - UpdateField<float, 70, 85> ModHealingPercent; - UpdateField<float, 70, 86> ModPeriodicHealingDonePercent; - UpdateField<float, 70, 87> ModSpellPowerPercent; - UpdateField<float, 70, 88> ModResiliencePercent; - UpdateField<float, 70, 89> OverrideSpellPowerByAPPercent; - UpdateField<float, 70, 90> OverrideAPBySpellPowerPercent; - UpdateField<int32, 70, 91> ModTargetResistance; - UpdateField<int32, 70, 92> ModTargetPhysicalResistance; - UpdateField<uint32, 70, 93> LocalFlags; - UpdateField<uint8, 70, 94> GrantableLevels; - UpdateField<uint8, 70, 95> MultiActionBars; - UpdateField<uint8, 70, 96> LifetimeMaxRank; - UpdateField<uint8, 70, 97> NumRespecs; - UpdateField<uint32, 70, 98> PvpMedals; - UpdateField<uint16, 70, 99> TodayHonorableKills; - UpdateField<uint16, 70, 100> YesterdayHonorableKills; - UpdateField<uint32, 70, 101> LifetimeHonorableKills; - UpdateField<int32, 102, 103> WatchedFactionIndex; - UpdateField<int32, 102, 104> MaxLevel; - UpdateField<int32, 102, 105> ScalingPlayerLevelDelta; - UpdateField<int32, 102, 106> MaxCreatureScalingLevel; - UpdateField<int32, 102, 107> PetSpellPower; - UpdateField<float, 102, 108> UiHitModifier; - UpdateField<float, 102, 109> UiSpellHitModifier; - UpdateField<int32, 102, 110> HomeRealmTimeOffset; - UpdateField<float, 102, 111> ModPetHaste; - UpdateField<int8, 102, 112> JailersTowerLevelMax; - UpdateField<int8, 102, 113> JailersTowerLevel; - UpdateField<uint8, 102, 114> LocalRegenFlags; - UpdateField<uint8, 102, 115> AuraVision; - UpdateField<uint8, 102, 116> NumBackpackSlots; - UpdateField<int32, 102, 117> OverrideSpellsID; - UpdateField<uint16, 102, 118> LootSpecID; - UpdateField<uint32, 102, 119> OverrideZonePVPType; - UpdateField<int32, 102, 120> Honor; - UpdateField<int32, 102, 121> HonorNextLevel; - UpdateField<int32, 102, 122> PerksProgramCurrency; - UpdateField<uint8, 102, 123> NumBankSlots; - UpdateField<uint8, 102, 124> NumCharacterBankTabs; - UpdateField<uint8, 102, 125> NumAccountBankTabs; - UpdateField<UF::ResearchHistory, 102, 126> ResearchHistory; - UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 102, 127> FrozenPerksVendorItem; - UpdateField<UF::ActivePlayerUnk901, 102, 129> Field_1410; - OptionalUpdateField<UF::QuestSession, 102, 128> QuestSession; - UpdateField<int32, 102, 130> UiChromieTimeExpansionID; - UpdateField<int32, 102, 131> TimerunningSeasonID; - UpdateField<int32, 102, 132> TransportServerTime; - UpdateField<uint32, 102, 133> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin - UpdateField<int16, 134, 135> DEBUGSoulbindConduitRank; - UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 134, 136> DungeonScore; - MapUpdateField<int32, UF::TraitConfig, 134, 137> TraitConfigs; - UpdateField<uint32, 134, 138> ActiveCombatTraitConfigID; - UpdateField<int32, 134, 139> ItemUpgradeHighOnehandWeaponItemID; - UpdateField<int32, 134, 140> ItemUpgradeHighFingerItemID; - UpdateField<float, 134, 141> ItemUpgradeHighFingerWatermark; - UpdateField<int32, 134, 142> ItemUpgradeHighTrinketItemID; - UpdateField<float, 134, 143> ItemUpgradeHighTrinketWatermark; - UpdateField<uint64, 134, 144> LootHistoryInstanceID; - OptionalUpdateField<UF::StableInfo, 134, 145> PetStable; - UpdateField<uint8, 134, 146> RequiredMountCapabilityFlags; - OptionalUpdateField<UF::WalkInData, 134, 147> WalkInData; - OptionalUpdateField<UF::DelveData, 134, 148> DelveData; - OptionalUpdateField<UF::ChallengeModeData, 134, 149> ChallengeModeData; - UpdateFieldArray<ObjectGuid, 105, 150, 151> InvSlots; - UpdateFieldArray<UF::RestInfo, 2, 256, 257> RestInfo; - UpdateFieldArray<int32, 7, 259, 260> ModDamageDonePos; - UpdateFieldArray<int32, 7, 259, 267> ModDamageDoneNeg; - UpdateFieldArray<float, 7, 259, 274> ModDamageDonePercent; - UpdateFieldArray<float, 7, 259, 281> ModHealingDonePercent; - UpdateFieldArray<float, 3, 288, 289> WeaponDmgMultipliers; - UpdateFieldArray<float, 3, 288, 292> WeaponAtkSpeedMultipliers; - UpdateFieldArray<uint32, 12, 295, 296> BuybackPrice; - UpdateFieldArray<int64, 12, 295, 308> BuybackTimestamp; - UpdateFieldArray<int32, 32, 320, 321> CombatRatings; - UpdateFieldArray<uint32, 4, 353, 354> NoReagentCostMask; - UpdateFieldArray<int32, 2, 358, 359> ProfessionSkillLine; - UpdateFieldArray<uint32, 5, 361, 362> BagSlotFlags; - UpdateFieldArray<float, 17, 367, 368> ItemUpgradeHighWatermark; + DynamicUpdateField<UF::CharacterRestriction, 0, 28> CharacterRestrictions; + DynamicUpdateField<UF::CraftingOrder, 32, 38> CraftingOrders; + DynamicUpdateField<UF::BankTabSettings, 32, 44> CharacterBankTabSettings; + DynamicUpdateField<UF::BankTabSettings, 32, 45> AccountBankTabSettings; + UpdateField<ObjectGuid, 32, 52> FarsightObject; + UpdateField<ObjectGuid, 32, 53> SummonedBattlePetGUID; + UpdateField<uint64, 32, 54> Coinage; + UpdateField<uint64, 32, 55> AccountBankCoinage; + UpdateField<int32, 32, 56> XP; + UpdateField<int32, 32, 57> NextLevelXP; + UpdateField<int32, 32, 58> TrialXP; + UpdateField<UF::SkillInfo, 32, 59> Skill; + UpdateField<int32, 32, 60> CharacterPoints; + UpdateField<int32, 32, 61> MaxTalentTiers; + UpdateField<uint32, 32, 62> TrackCreatureMask; + UpdateField<float, 32, 63> MainhandExpertise; + UpdateField<float, 32, 64> OffhandExpertise; + UpdateField<float, 32, 65> RangedExpertise; + UpdateField<float, 32, 66> CombatRatingExpertise; + UpdateField<float, 32, 67> BlockPercentage; + UpdateField<float, 32, 68> DodgePercentage; + UpdateField<float, 32, 69> DodgePercentageFromAttribute; + UpdateField<float, 70, 71> ParryPercentage; + UpdateField<float, 70, 72> ParryPercentageFromAttribute; + UpdateField<float, 70, 73> CritPercentage; + UpdateField<float, 70, 74> RangedCritPercentage; + UpdateField<float, 70, 75> OffhandCritPercentage; + UpdateField<float, 70, 76> SpellCritPercentage; + UpdateField<int32, 70, 77> ShieldBlock; + UpdateField<float, 70, 78> ShieldBlockCritPercentage; + UpdateField<float, 70, 79> Mastery; + UpdateField<float, 70, 80> Speed; + UpdateField<float, 70, 81> Avoidance; + UpdateField<float, 70, 82> Sturdiness; + UpdateField<int32, 70, 83> Versatility; + UpdateField<float, 70, 84> VersatilityBonus; + UpdateField<float, 70, 85> PvpPowerDamage; + UpdateField<float, 70, 86> PvpPowerHealing; + UpdateField<UF::BitVectors, 70, 87> BitVectors; + UpdateField<int32, 70, 88> ModHealingDonePos; + UpdateField<float, 70, 89> ModHealingPercent; + UpdateField<float, 70, 90> ModPeriodicHealingDonePercent; + UpdateField<float, 70, 91> ModSpellPowerPercent; + UpdateField<float, 70, 92> ModResiliencePercent; + UpdateField<float, 70, 93> OverrideSpellPowerByAPPercent; + UpdateField<float, 70, 94> OverrideAPBySpellPowerPercent; + UpdateField<int32, 70, 95> ModTargetResistance; + UpdateField<int32, 70, 96> ModTargetPhysicalResistance; + UpdateField<uint32, 70, 97> LocalFlags; + UpdateField<uint8, 70, 98> GrantableLevels; + UpdateField<uint8, 70, 99> MultiActionBars; + UpdateField<uint8, 70, 100> LifetimeMaxRank; + UpdateField<uint8, 70, 101> NumRespecs; + UpdateField<uint32, 102, 103> PvpMedals; + UpdateField<uint16, 102, 104> TodayHonorableKills; + UpdateField<uint16, 102, 105> YesterdayHonorableKills; + UpdateField<uint32, 102, 106> LifetimeHonorableKills; + UpdateField<int32, 102, 107> WatchedFactionIndex; + UpdateField<int32, 102, 108> MaxLevel; + UpdateField<int32, 102, 109> ScalingPlayerLevelDelta; + UpdateField<int32, 102, 110> MaxCreatureScalingLevel; + UpdateField<int32, 102, 111> PetSpellPower; + UpdateField<float, 102, 112> UiHitModifier; + UpdateField<float, 102, 113> UiSpellHitModifier; + UpdateField<int32, 102, 114> HomeRealmTimeOffset; + UpdateField<float, 102, 115> ModPetHaste; + UpdateField<int8, 102, 116> JailersTowerLevelMax; + UpdateField<int8, 102, 117> JailersTowerLevel; + UpdateField<uint8, 102, 118> LocalRegenFlags; + UpdateField<uint8, 102, 119> AuraVision; + UpdateField<uint8, 102, 120> NumBackpackSlots; + UpdateField<int32, 102, 121> OverrideSpellsID; + UpdateField<uint16, 102, 122> LootSpecID; + UpdateField<uint32, 102, 123> OverrideZonePVPType; + UpdateField<int32, 102, 124> Honor; + UpdateField<int32, 102, 125> HonorNextLevel; + UpdateField<int32, 102, 126> PerksProgramCurrency; + UpdateField<uint8, 102, 127> NumBankSlots; + UpdateField<uint8, 102, 128> NumCharacterBankTabs; + UpdateField<uint8, 102, 129> NumAccountBankTabs; + UpdateField<UF::ResearchHistory, 102, 130> ResearchHistory; + UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 102, 131> FrozenPerksVendorItem; + UpdateField<UF::ActivePlayerUnk901, 102, 133> Field_1410; + OptionalUpdateField<UF::QuestSession, 102, 132> QuestSession; + UpdateField<int32, 134, 135> UiChromieTimeExpansionID; + UpdateField<int32, 134, 136> TimerunningSeasonID; + UpdateField<int32, 134, 137> TransportServerTime; + UpdateField<uint32, 134, 138> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin + UpdateField<int16, 134, 139> DEBUGSoulbindConduitRank; + UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 134, 140> DungeonScore; + MapUpdateField<int32, UF::TraitConfig, 134, 141> TraitConfigs; + UpdateField<uint32, 134, 142> ActiveCombatTraitConfigID; + UpdateField<int32, 134, 143> ItemUpgradeHighOnehandWeaponItemID; + UpdateField<int32, 134, 144> ItemUpgradeHighFingerItemID; + UpdateField<float, 134, 145> ItemUpgradeHighFingerWatermark; + UpdateField<int32, 134, 146> ItemUpgradeHighTrinketItemID; + UpdateField<float, 134, 147> ItemUpgradeHighTrinketWatermark; + UpdateField<uint64, 134, 148> LootHistoryInstanceID; + OptionalUpdateField<UF::StableInfo, 134, 149> PetStable; + UpdateField<uint8, 134, 150> RequiredMountCapabilityFlags; + OptionalUpdateField<UF::WalkInData, 134, 151> WalkInData; + OptionalUpdateField<UF::DelveData, 134, 152> DelveData; + OptionalUpdateField<UF::ChallengeModeData, 134, 153> ChallengeModeData; + UpdateFieldArray<ObjectGuid, 105, 154, 155> InvSlots; + UpdateFieldArray<UF::RestInfo, 2, 260, 261> RestInfo; + UpdateFieldArray<int32, 7, 263, 264> ModDamageDonePos; + UpdateFieldArray<int32, 7, 263, 271> ModDamageDoneNeg; + UpdateFieldArray<float, 7, 263, 278> ModDamageDonePercent; + UpdateFieldArray<float, 7, 263, 285> ModHealingDonePercent; + UpdateFieldArray<float, 3, 292, 293> WeaponDmgMultipliers; + UpdateFieldArray<float, 3, 292, 296> WeaponAtkSpeedMultipliers; + UpdateFieldArray<uint32, 12, 299, 300> BuybackPrice; + UpdateFieldArray<int64, 12, 299, 312> BuybackTimestamp; + UpdateFieldArray<int32, 32, 324, 325> CombatRatings; + UpdateFieldArray<uint32, 4, 357, 358> NoReagentCostMask; + UpdateFieldArray<int32, 2, 362, 363> ProfessionSkillLine; + UpdateFieldArray<uint32, 5, 365, 366> BagSlotFlags; + UpdateFieldArray<float, 17, 371, 372> ItemUpgradeHighWatermark; void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; @@ -1377,7 +1383,7 @@ struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5> struct ForceSetAreaTriggerPositionAndRotation : public IsUpdateFieldStructureTag { ObjectGuid TriggerGUID; - TaggedPosition<::Position::XYZ> Position; + TaggedPosition<Position::XYZ> Position; QuaternionData Rotation; void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; @@ -1599,6 +1605,30 @@ struct ConversationData : public IsUpdateFieldStructureTag, public HasChangesMas void ClearChangesMask(); }; +struct AaBox : public IsUpdateFieldStructureTag +{ + TaggedPosition<Position::XYZ> Low; + TaggedPosition<Position::XYZ> High; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + bool operator==(AaBox const& right) const; + bool operator!=(AaBox const& right) const { return !(*this == right); } +}; + +struct MeshObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<5> +{ + UpdateField<bool, 0, 1> IsWMO; + UpdateField<bool, 0, 2> IsRoom; + UpdateField<int32, 0, 3> FileDataID; + OptionalUpdateField<AaBox, 0, 4> Geobox; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + struct VendorData : public IsUpdateFieldStructureTag, public HasChangesMask<2> { UpdateField<int32, 0, 1> Flags; @@ -1609,6 +1639,272 @@ struct VendorData : public IsUpdateFieldStructureTag, public HasChangesMask<2> void ClearChangesMask(); }; +struct DecorStoragePersistedDataDyes : public IsUpdateFieldStructureTag +{ + int32 DyeColorID[3]; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + bool operator==(DecorStoragePersistedDataDyes const& right) const; + bool operator!=(DecorStoragePersistedDataDyes const& right) const { return !(*this == right); } +}; + +struct DecorStoragePersistedData : public IsUpdateFieldStructureTag, public HasChangesMask<4> +{ + UpdateField<ObjectGuid, 0, 1> HouseGUID; + OptionalUpdateField<UF::DecorStoragePersistedDataDyes, 0, 2> Dyes; + UpdateField<uint8, 0, 3> Field_20; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingDecorData : public IsUpdateFieldStructureTag, public HasChangesMask<6> +{ + UpdateField<ObjectGuid, 0, 1> DecorGUID; + UpdateField<ObjectGuid, 0, 2> AttachParentGUID; + UpdateField<uint8, 0, 3> Flags; + OptionalUpdateField<UF::DecorStoragePersistedData, 0, 4> PersistedData; + UpdateField<ObjectGuid, 0, 5> Field_68; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingDoorData : public IsUpdateFieldStructureTag, public HasChangesMask<5> +{ + UpdateField<int32, 0, 1> RoomComponentID; + UpdateField<TaggedPosition<Position::XYZ>, 0, 2> RoomComponentOffset; + UpdateField<uint8, 0, 3> RoomComponentType; + UpdateField<ObjectGuid, 0, 4> AttachedRoomGUID; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingRoomData : public IsUpdateFieldStructureTag, public HasChangesMask<7> +{ + DynamicUpdateField<ObjectGuid, 0, 1> MeshObjects; + DynamicUpdateField<UF::HousingDoorData, 0, 2> Doors; + UpdateField<ObjectGuid, 0, 3> HouseGUID; + UpdateField<int32, 0, 4> HouseRoomID; + UpdateField<int32, 0, 5> Flags; + UpdateField<int32, 0, 6> FloorIndex; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingRoomComponentMeshData : public IsUpdateFieldStructureTag, public HasChangesMask<10> +{ + UpdateField<ObjectGuid, 0, 1> RoomGUID; + UpdateField<int32, 0, 2> RoomComponentOptionID; + UpdateField<int32, 0, 3> RoomComponentID; + UpdateField<uint8, 0, 4> Field_20; + UpdateField<uint8, 0, 5> RoomComponentType; + UpdateField<int32, 0, 6> Field_24; + UpdateField<int32, 0, 7> HouseThemeID; + UpdateField<int32, 0, 8> RoomComponentTextureID; + UpdateField<int32, 0, 9> RoomComponentTypeParam; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingPlayerHouseData : public IsUpdateFieldStructureTag, public HasChangesMask<10> +{ + UpdateField<ObjectGuid, 0, 1> BnetAccount; + UpdateField<int32, 0, 2> PlotIndex; + UpdateField<uint32, 0, 3> Level; + UpdateField<uint64, 0, 4> Field_20; + UpdateField<uint32, 0, 5> InteriorDecorPlacementBudget; + UpdateField<uint32, 0, 6> ExteriorDecorPlacementBudget; + UpdateField<uint32, 0, 7> ExteriorFixtureBudget; + UpdateField<uint32, 0, 8> RoomPlacementBudget; + UpdateField<ObjectGuid, 0, 9> EntityGUID; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingCornerstoneData : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + UpdateField<uint64, 0, 1> Cost; + UpdateField<int32, 0, 2> PlotIndex; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingPlotAreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<5> +{ + UpdateField<uint32, 0, 1> Field_0; + UpdateField<ObjectGuid, 0, 2> HouseOwnerGUID; + UpdateField<ObjectGuid, 0, 3> HouseGUID; + UpdateField<ObjectGuid, 0, 4> HouseOwnerBnetAccountGUID; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct PlayerHouseInfo : public IsUpdateFieldStructureTag +{ + ObjectGuid HouseGUID; + ObjectGuid OwnerGUID; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + bool operator==(PlayerHouseInfo const& right) const; + bool operator!=(PlayerHouseInfo const& right) const { return !(*this == right); } +}; + +struct HousingOwner : public IsUpdateFieldStructureTag +{ + ObjectGuid BnetAccountGUID; + ObjectGuid PlayerGUID; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + bool operator==(HousingOwner const& right) const; + bool operator!=(HousingOwner const& right) const { return !(*this == right); } +}; + +struct NeighborhoodMirrorData : public IsUpdateFieldStructureTag, public HasChangesMask<5> +{ + DynamicUpdateField<UF::PlayerHouseInfo, 0, 1> Houses; + DynamicUpdateField<UF::HousingOwner, 0, 2> Managers; + UpdateField<ObjectGuid, 0, 4> OwnerGUID; + UpdateField<std::string, 0, 3> Name; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct MirroredMeshObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<6> +{ + UpdateField<ObjectGuid, 0, 1> AttachParentGUID; + UpdateField<TaggedPosition<Position::XYZ>, 0, 2> PositionLocalSpace; + UpdateField<QuaternionData, 0, 3> RotationLocalSpace; + UpdateField<float, 0, 4> ScaleLocalSpace; + UpdateField<uint8, 0, 5> AttachmentFlags; + + void WriteCreate(ByteBuffer& data, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct MirroredPositionData : public IsUpdateFieldStructureTag, public HasChangesMask<2> +{ + UpdateField<UF::MirroredMeshObjectData, 0, 1> PositionData; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct PlayerMirrorHouse : public IsUpdateFieldStructureTag +{ + ObjectGuid Guid; + ObjectGuid NeighborhoodGUID; + uint32 Level; + uint32 Favor; + int32 Field_28; + + void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; + bool operator==(PlayerMirrorHouse const& right) const; + bool operator!=(PlayerMirrorHouse const& right) const { return !(*this == right); } +}; + +struct NeighborhoodCharterSignature : public IsUpdateFieldStructureTag +{ + ObjectGuid Guid; + + void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; + bool operator==(NeighborhoodCharterSignature const& right) const; + bool operator!=(NeighborhoodCharterSignature const& right) const { return !(*this == right); } +}; + +struct NeighborhoodCharter : public IsUpdateFieldStructureTag +{ + std::vector<UF::NeighborhoodCharterSignature> Signatures; + int32 Field_0; + int32 Field_4; + std::string Name; + + void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; + bool operator==(NeighborhoodCharter const& right) const; + bool operator!=(NeighborhoodCharter const& right) const { return !(*this == right); } +}; + +struct PlayerHouseInfoComponentData : public IsUpdateFieldStructureTag, public HasChangesMask<9> +{ + DynamicUpdateField<ObjectGuid, 0, 1> Field_8; + DynamicUpdateField<UF::PlayerMirrorHouse, 0, 2> Houses; + DynamicUpdateField<ObjectGuid, 0, 3> Field_88; + DynamicUpdateField<ObjectGuid, 0, 4> Field_C0; + DynamicUpdateField<ObjectGuid, 0, 5> Field_F8; + UpdateField<ObjectGuid, 0, 6> Field_40; + UpdateField<UF::NeighborhoodCharter, 0, 7> Charter; + UpdateField<uint8, 0, 8> Field_178; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const; + static void AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags); + static void FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags); + void ClearChangesMask(); +}; + +struct HousingStorageData : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + MapUpdateField<ObjectGuid, UF::DecorStoragePersistedData, 0, 1> Decor; + UpdateField<uint32, 0, 2> DecorMaxOwnedCount; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct HousingFixtureData : public IsUpdateFieldStructureTag, public HasChangesMask<11> +{ + UpdateField<int32, 0, 1> ExteriorComponentID; + UpdateField<int32, 0, 2> HouseExteriorWmoDataID; + UpdateField<int32, 0, 3> ExteriorComponentHookID; + UpdateField<ObjectGuid, 0, 4> HouseGUID; + UpdateField<ObjectGuid, 0, 5> AttachParentGUID; + UpdateField<ObjectGuid, 0, 6> Guid; + UpdateField<ObjectGuid, 0, 7> GameObjectGUID; + UpdateField<uint8, 0, 8> ExteriorComponentType; + UpdateField<uint8, 0, 9> Field_59; + UpdateField<uint8, 0, 10> Size; + + void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + } #endif // UpdateFields_h__ diff --git a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h index a65ca60978a..f3d8182ff83 100644 --- a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h +++ b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h @@ -26,44 +26,77 @@ namespace WowCS { enum class EntityFragment : uint8 { - CGObject = 0, // UPDATEABLE, INDIRECT, - Tag_Item = 1, // TAG, - Tag_Container = 2, // TAG, - Tag_AzeriteEmpoweredItem = 3, // TAG, - Tag_AzeriteItem = 4, // TAG, - Tag_Unit = 5, // TAG, - Tag_Player = 6, // TAG, - Tag_GameObject = 7, // TAG, - Tag_DynamicObject = 8, // TAG, - Tag_Corpse = 9, // TAG, - Tag_AreaTrigger = 10, // TAG, - Tag_SceneObject = 11, // TAG, - Tag_Conversation = 12, // TAG, - Tag_AIGroup = 13, // TAG, - Tag_Scenario = 14, // TAG, - Tag_LootObject = 15, // TAG, - Tag_ActivePlayer = 16, // TAG, - Tag_ActiveClient_S = 17, // TAG, - Tag_ActiveObject_C = 18, // TAG, - Tag_VisibleObject_C = 19, // TAG, - Tag_UnitVehicle = 20, // TAG, - FEntityPosition = 112, - FEntityLocalMatrix = 113, - FEntityWorldMatrix = 114, - CActor = 115, // INDIRECT, - FVendor_C = 117, // UPDATEABLE, INDIRECT, - FMirroredObject_C = 119, + FEntityPosition = 1, + CGObject = 2, // UPDATEABLE, INDIRECT, + FTransportLink = 5, + FPlayerOwnershipLink = 13, // INDIRECT, + CActor = 15, // INDIRECT, + FVendor_C = 17, // UPDATEABLE, + FMirroredObject_C = 18, + FMeshObjectData_C = 19, // UPDATEABLE, + FHousingDecor_C = 20, // UPDATEABLE, + FHousingRoom_C = 21, // UPDATEABLE, + FHousingRoomComponentMesh_C = 22, // UPDATEABLE, + FHousingPlayerHouse_C = 23, // UPDATEABLE, + FJamHousingCornerstone_C = 27, // UPDATEABLE, + FHousingDecorActor_C = 28, + FHousingPlotAreaTrigger_C = 29, // UPDATEABLE, + FNeighborhoodMirrorData_C = 30, // UPDATEABLE, + FMirroredPositionData_C = 31, // UPDATEABLE, + PlayerHouseInfoComponent_C = 32, // UPDATEABLE, INDIRECT, + FHousingStorage_C = 33, // UPDATEABLE, + FHousingFixture_C = 34, // UPDATEABLE, + Tag_Item = 200, // TAG, + Tag_Container = 201, // TAG, + Tag_AzeriteEmpoweredItem = 202, // TAG, + Tag_AzeriteItem = 203, // TAG, + Tag_Unit = 204, // TAG, + Tag_Player = 205, // TAG, + Tag_GameObject = 206, // TAG, + Tag_DynamicObject = 207, // TAG, + Tag_Corpse = 208, // TAG, + Tag_AreaTrigger = 209, // TAG, + Tag_SceneObject = 210, // TAG, + Tag_Conversation = 211, // TAG, + Tag_AIGroup = 212, // TAG, + Tag_Scenario = 213, // TAG, + Tag_LootObject = 214, // TAG, + Tag_ActivePlayer = 215, // TAG, + Tag_ActiveClient_S = 216, // TAG, + Tag_ActiveObject_C = 217, // TAG, + Tag_VisibleObject_C = 218, // TAG, + Tag_UnitVehicle = 219, // TAG, + Tag_HousingRoom = 220, // TAG, + Tag_MeshObject = 221, // TAG, + Tag_HouseExteriorPiece = 224, // TAG, + Tag_HouseExteriorRoot = 225, // TAG, End = 255, }; inline constexpr bool IsUpdateableFragment(EntityFragment frag) { - return frag == EntityFragment::CGObject || frag == EntityFragment::FVendor_C; + return frag == EntityFragment::CGObject + || frag == EntityFragment::FVendor_C + || frag == EntityFragment::FMeshObjectData_C + || frag == EntityFragment::FHousingDecor_C + || frag == EntityFragment::FHousingRoom_C + || frag == EntityFragment::FHousingRoomComponentMesh_C + || frag == EntityFragment::FHousingPlayerHouse_C + || frag == EntityFragment::FJamHousingCornerstone_C + || frag == EntityFragment::FHousingPlotAreaTrigger_C + || frag == EntityFragment::FNeighborhoodMirrorData_C + || frag == EntityFragment::FMirroredPositionData_C + || frag == EntityFragment::PlayerHouseInfoComponent_C + || frag == EntityFragment::FHousingStorage_C + || frag == EntityFragment::FHousingFixture_C; } inline constexpr bool IsIndirectFragment(EntityFragment frag) { - return frag == EntityFragment::CGObject || frag == EntityFragment::CActor || frag == EntityFragment::FVendor_C; + return frag == EntityFragment::CGObject + || frag == EntityFragment::FPlayerOwnershipLink + || frag == EntityFragment::CActor + || frag == EntityFragment::PlayerHouseInfoComponent_C; } // common case optimization, make use of the fact that fragment arrays are sorted @@ -81,8 +114,11 @@ struct EntityFragmentsHolder uint8 Count = 0; bool IdsChanged = false; - std::array<EntityFragment, 2> UpdateableIds = { EntityFragment::End, EntityFragment::End }; - std::array<uint8, 2> UpdateableMasks = { }; + std::array<EntityFragment, 4> UpdateableIds = + { + EntityFragment::End, EntityFragment::End, EntityFragment::End, EntityFragment::End + }; + std::array<uint8, 4> UpdateableMasks = { }; uint8 UpdateableCount = 0; uint8 ContentsChangedMask = 0; |
