From 23624ed75abc8cbb77bb2e24a08e0836e4c41db5 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 2 Mar 2025 15:43:34 +0100 Subject: Core: Updated to 11.1.0 --- src/server/game/Entities/Object/MovementInfo.h | 17 + src/server/game/Entities/Object/Object.cpp | 21 +- src/server/game/Entities/Object/Object.h | 19 +- .../game/Entities/Object/Updates/UpdateFields.cpp | 633 +++++++++++---------- .../game/Entities/Object/Updates/UpdateFields.h | 473 +++++++-------- .../Object/Updates/ViewerDependentValues.h | 12 + .../Object/Updates/WowCSEntityDefinitions.cpp | 8 +- .../Object/Updates/WowCSEntityDefinitions.h | 4 +- 8 files changed, 648 insertions(+), 539 deletions(-) (limited to 'src/server/game/Entities/Object') diff --git a/src/server/game/Entities/Object/MovementInfo.h b/src/server/game/Entities/Object/MovementInfo.h index 65a044ecbe4..f7defefe5d0 100644 --- a/src/server/game/Entities/Object/MovementInfo.h +++ b/src/server/game/Entities/Object/MovementInfo.h @@ -92,12 +92,26 @@ struct MovementInfo // advflying struct AdvFlying { + AdvFlying() : forwardVelocity(0.0f), upVelocity(0.0f) { } + float forwardVelocity; float upVelocity; }; + struct Drive + { + Drive() : speed(0.0f), movementAngle(0.0f), accelerating(false), drifting(false) { } + + float speed; + float movementAngle; + bool accelerating; + bool drifting; + }; + Optional advFlying; + Optional driveStatus; + Optional standingOnGameObjectGUID; uint32 GetMovementFlags() const { return flags; } @@ -149,6 +163,9 @@ struct MovementForce float Magnitude = 0.0f; MovementForceType Type = MovementForceType::SingleDirectional; int32 MovementForceID = 0; + int32 Unknown1110_1 = 0; + int32 Unused1110 = 0; + uint32 Flags = 0; }; class MovementForces diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index b5728d43395..7c5570488de 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -247,11 +247,16 @@ void Object::BuildEntityFragments(ByteBuffer* data, std::span(WowCS::EntityFragment::End); } -void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag flags) +void Object::BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag flags) const { + uint8 contentsChangedMask = WowCS::CGObjectChangedMask; + for (WowCS::EntityFragment updateableFragmentId : m_entityFragments.GetUpdateableIds()) + if (WowCS::IsIndirectFragment(updateableFragmentId)) + contentsChangedMask |= m_entityFragments.GetUpdateMaskFor(updateableFragmentId) >> 1; // set the "fragment exists" bit + *data << uint8(flags.HasFlag(UF::UpdateFieldFlag::Owner)); *data << uint8(false); // m_entityFragments.IdsChanged - *data << uint8(WowCS::CGObjectUpdateMask); + *data << uint8(contentsChangedMask); } void Object::BuildDestroyUpdateBlock(UpdateData* data) const @@ -329,6 +334,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe bool HasSpline = unit->IsSplineEnabled(); bool HasInertia = unit->m_movementInfo.inertia.has_value(); bool HasAdvFlying = unit->m_movementInfo.advFlying.has_value(); + bool HasDriveStatus = unit->m_movementInfo.driveStatus.has_value(); bool HasStandingOnGameObjectGUID = unit->m_movementInfo.standingOnGameObjectGUID.has_value(); *data << GetGUID(); // MoverGUID @@ -360,6 +366,8 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe data->WriteBit(false); // RemoteTimeValid data->WriteBit(HasInertia); // HasInertia data->WriteBit(HasAdvFlying); // HasAdvFlying + data->WriteBit(HasDriveStatus); // HasDriveStatus + data->FlushBits(); if (!unit->m_movementInfo.transport.guid.IsEmpty()) *data << unit->m_movementInfo.transport; @@ -393,6 +401,14 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe } } + if (HasDriveStatus) + { + data->WriteBit(unit->m_movementInfo.driveStatus->accelerating); + data->WriteBit(unit->m_movementInfo.driveStatus->drifting); + *data << float(unit->m_movementInfo.driveStatus->speed); + *data << float(unit->m_movementInfo.driveStatus->movementAngle); + } + *data << float(unit->GetSpeed(MOVE_WALK)); *data << float(unit->GetSpeed(MOVE_RUN)); *data << float(unit->GetSpeed(MOVE_RUN_BACK)); @@ -838,7 +854,6 @@ void Object::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&Object::m_objectData); m_entityFragments.IdsChanged = false; - m_entityFragments.ContentsChangedMask = WowCS::CGObjectActiveMask; if (m_objectUpdated) { diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 2e96f92c59d..c9f0fdd04ed 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -433,7 +433,7 @@ class TC_GAME_API Object virtual void BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const = 0; virtual void BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const = 0; static void BuildEntityFragments(ByteBuffer* data, std::span fragments); - static void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag flags); + void BuildEntityFragmentsForValuesUpdateForPlayerWithMask(ByteBuffer* data, EnumFlag flags) const; public: virtual void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const; @@ -523,7 +523,13 @@ inline void UF::UpdateFieldHolder::ClearChangesMask(UpdateFieldm_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); if constexpr (WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject) + { _changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit); + if (!_changesMask) + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); + } + else + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); (static_cast(owner)->*field)._value.ClearChangesMask(); } @@ -532,11 +538,18 @@ template inline void UF::UpdateFieldHolder::ClearChangesMask(OptionalUpdateField Derived::* field) { Object* owner = GetOwner(); - owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); if constexpr (WowCS::EntityFragment(BlockBit) == WowCS::EntityFragment::CGObject) + { _changesMask &= ~UpdateMaskHelpers::GetBlockFlag(Bit); + if (!_changesMask) + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); + } + else + owner->m_entityFragments.ContentsChangedMask &= ~owner->m_entityFragments.GetUpdateMaskFor(WowCS::EntityFragment(BlockBit)); - (static_cast(owner)->*field)._value->ClearChangesMask(); + auto& uf = (static_cast(owner)->*field); + if (uf.has_value()) + uf._value->ClearChangesMask(); } template diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 83784f90050..cc073ad6592 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -929,7 +929,7 @@ bool PassiveSpellHistory::operator==(PassiveSpellHistory const& right) const void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Unit const* owner, Player const* receiver) const { - ViewerDependentValue::value_type stateWorldEffectIDs = ViewerDependentValue::GetValue(this, owner, receiver); + ViewerDependentValue::value_type stateWorldEffectIDs = {}; data << int32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); @@ -937,6 +937,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisi data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); + stateWorldEffectIDs = ViewerDependentValue::GetValue(this, owner, receiver); data << uint32(stateWorldEffectIDs->size()); data << uint32(StateWorldEffectsQuestObjectiveID); data << int32(SpellOverrideNameID); @@ -988,7 +989,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisi data << int32(ScalingLevelMin); data << int32(ScalingLevelMax); data << int32(ScalingLevelDelta); - data << int32(ScalingFactionGroup); + data << uint8(ScalingFactionGroup); data << int32(ViewerDependentValue::GetValue(this, owner, receiver)); for (uint32 i = 0; i < 3; ++i) { @@ -997,6 +998,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisi data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); + data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); for (uint32 i = 0; i < 2; ++i) { @@ -1010,7 +1012,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisi data << float(CombatReach); data << float(DisplayScale); data << int32(CreatureFamily); - data << int32(CreatureType); + data << uint8(CreatureType); data << int32(NativeDisplayID); data << float(NativeXDisplayScale); data << int32(MountDisplayID); @@ -1116,6 +1118,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisi data << uint32(ChannelObjects.size()); data << int32(FlightCapabilityID); data << float(GlideEventSpeedDivisor); + data << int32(DriveCapabilityID); data << int32(MaxHealthModifierFlatNeg); data << int32(MaxHealthModifierFlatPos); data << uint32(SilencedSchoolMask); @@ -1141,7 +1144,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisi void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Unit const* owner, Player const* receiver) const { - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x87FDFFFFu, 0x007BFFFFu, 0xFFFFFC01u, 0x03FFFFFFu, 0x001FC000u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -1149,16 +1152,16 @@ void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag fieldVisi void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array{ 0x00010000u, 0x78020000u, 0xFF840000u, 0x000003FEu, 0xFC000020u, 0xFFE03FFFu, 0x0FFFFFFFu }; + allowedMaskForTarget |= std::array{ 0x00010000u, 0xF0040000u, 0xFF080000u, 0x000007FEu, 0xF0000080u, 0xFF80FFFFu, 0x3FFFFFFFu }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) - allowedMaskForTarget |= std::array{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFC000020u, 0x00003FFFu, 0x00000000u }; + allowedMaskForTarget |= std::array{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xF0000080u, 0x0000FFFFu, 0x00000000u }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) - allowedMaskForTarget |= std::array{ 0x00000000u, 0x78000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00003FC0u }; + allowedMaskForTarget |= std::array{ 0x00000000u, 0xF0000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0000FF00u }; } void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x87FDFFFFu, 0x007BFFFFu, 0xFFFFFC01u, 0x03FFFFFFu, 0x001FC000u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } @@ -1395,7 +1398,7 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor } if (changesMask[43]) { - data << int32(ScalingFactionGroup); + data << uint8(ScalingFactionGroup); } if (changesMask[44]) { @@ -1415,419 +1418,427 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor } if (changesMask[48]) { - data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); + data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); } if (changesMask[49]) { - data << uint32(RangedAttackRoundBaseTime); + data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); } if (changesMask[50]) { - data << float(BoundingRadius); + data << uint32(RangedAttackRoundBaseTime); } if (changesMask[51]) { - data << float(CombatReach); + data << float(BoundingRadius); } if (changesMask[52]) { - data << float(DisplayScale); + data << float(CombatReach); } if (changesMask[53]) { - data << int32(CreatureFamily); + data << float(DisplayScale); } if (changesMask[54]) { - data << int32(CreatureType); + data << int32(CreatureFamily); } if (changesMask[55]) { - data << int32(NativeDisplayID); + data << uint8(CreatureType); } if (changesMask[56]) { - data << float(NativeXDisplayScale); + data << int32(NativeDisplayID); } if (changesMask[57]) { - data << int32(MountDisplayID); + data << float(NativeXDisplayScale); } if (changesMask[58]) { - data << int32(CosmeticMountDisplayID); + data << int32(MountDisplayID); } if (changesMask[59]) { - data << float(MinDamage); + data << int32(CosmeticMountDisplayID); } if (changesMask[60]) { - data << float(MaxDamage); + data << float(MinDamage); } if (changesMask[61]) { - data << float(MinOffHandDamage); + data << float(MaxDamage); } if (changesMask[62]) { - data << float(MaxOffHandDamage); + data << float(MinOffHandDamage); } if (changesMask[63]) { - data << uint8(StandState); + data << float(MaxOffHandDamage); } } if (changesMask[64]) { if (changesMask[65]) { - data << uint8(PetTalentPoints); + data << uint8(StandState); } if (changesMask[66]) { - data << uint8(VisFlags); + data << uint8(PetTalentPoints); } if (changesMask[67]) { - data << uint8(AnimTier); + data << uint8(VisFlags); } if (changesMask[68]) { - data << uint32(PetNumber); + data << uint8(AnimTier); } if (changesMask[69]) { - data << uint32(PetNameTimestamp); + data << uint32(PetNumber); } if (changesMask[70]) { - data << uint32(PetExperience); + data << uint32(PetNameTimestamp); } if (changesMask[71]) { - data << uint32(PetNextLevelExperience); + data << uint32(PetExperience); } if (changesMask[72]) { - data << float(ModCastingSpeed); + data << uint32(PetNextLevelExperience); } if (changesMask[73]) { - data << float(ModCastingSpeedNeg); + data << float(ModCastingSpeed); } if (changesMask[74]) { - data << float(ModSpellHaste); + data << float(ModCastingSpeedNeg); } if (changesMask[75]) { - data << float(ModHaste); + data << float(ModSpellHaste); } if (changesMask[76]) { - data << float(ModRangedHaste); + data << float(ModHaste); } if (changesMask[77]) { - data << float(ModHasteRegen); + data << float(ModRangedHaste); } if (changesMask[78]) { - data << float(ModTimeRate); + data << float(ModHasteRegen); } if (changesMask[79]) { - data << int32(CreatedBySpell); + data << float(ModTimeRate); } if (changesMask[80]) { - data << int32(EmoteState); + data << int32(CreatedBySpell); } if (changesMask[81]) { - data << int32(BaseMana); + data << int32(EmoteState); } if (changesMask[82]) { - data << int32(BaseHealth); + data << int32(BaseMana); } if (changesMask[83]) { - data << uint8(SheatheState); + data << int32(BaseHealth); } if (changesMask[84]) { - data << uint8(ViewerDependentValue::GetValue(this, owner, receiver)); + data << uint8(SheatheState); } if (changesMask[85]) { - data << uint8(PetFlags); + data << uint8(ViewerDependentValue::GetValue(this, owner, receiver)); } if (changesMask[86]) { - data << uint8(ShapeshiftForm); + data << uint8(PetFlags); } if (changesMask[87]) { - data << int32(AttackPower); + data << uint8(ShapeshiftForm); } if (changesMask[88]) { - data << int32(AttackPowerModPos); + data << int32(AttackPower); } if (changesMask[89]) { - data << int32(AttackPowerModNeg); + data << int32(AttackPowerModPos); } if (changesMask[90]) { - data << float(AttackPowerMultiplier); + data << int32(AttackPowerModNeg); } if (changesMask[91]) { - data << int32(AttackPowerModSupport); + data << float(AttackPowerMultiplier); } if (changesMask[92]) { - data << int32(RangedAttackPower); + data << int32(AttackPowerModSupport); } if (changesMask[93]) { - data << int32(RangedAttackPowerModPos); + data << int32(RangedAttackPower); } if (changesMask[94]) { - data << int32(RangedAttackPowerModNeg); + data << int32(RangedAttackPowerModPos); } if (changesMask[95]) { - data << float(RangedAttackPowerMultiplier); + data << int32(RangedAttackPowerModNeg); } } if (changesMask[96]) { if (changesMask[97]) { - data << int32(RangedAttackPowerModSupport); + data << float(RangedAttackPowerMultiplier); } if (changesMask[98]) { - data << int32(MainHandWeaponAttackPower); + data << int32(RangedAttackPowerModSupport); } if (changesMask[99]) { - data << int32(OffHandWeaponAttackPower); + data << int32(MainHandWeaponAttackPower); } if (changesMask[100]) { - data << int32(RangedWeaponAttackPower); + data << int32(OffHandWeaponAttackPower); } if (changesMask[101]) { - data << int32(SetAttackSpeedAura); + data << int32(RangedWeaponAttackPower); } if (changesMask[102]) { - data << float(Lifesteal); + data << int32(SetAttackSpeedAura); } if (changesMask[103]) { - data << float(MinRangedDamage); + data << float(Lifesteal); } if (changesMask[104]) { - data << float(MaxRangedDamage); + data << float(MinRangedDamage); } if (changesMask[105]) { - data << float(ManaCostMultiplier); + data << float(MaxRangedDamage); } if (changesMask[106]) { - data << float(MaxHealthModifier); + data << float(ManaCostMultiplier); } if (changesMask[107]) { - data << float(HoverHeight); + data << float(MaxHealthModifier); } if (changesMask[108]) { - data << int32(MinItemLevelCutoff); + data << float(HoverHeight); } if (changesMask[109]) { - data << int32(MinItemLevel); + data << int32(MinItemLevelCutoff); } if (changesMask[110]) { - data << int32(MaxItemLevel); + data << int32(MinItemLevel); } if (changesMask[111]) { - data << int32(AzeriteItemLevel); + data << int32(MaxItemLevel); } if (changesMask[112]) { - data << int32(WildBattlePetLevel); + data << int32(AzeriteItemLevel); } if (changesMask[113]) { - data << int32(BattlePetCompanionExperience); + data << int32(WildBattlePetLevel); } if (changesMask[114]) { - data << uint32(BattlePetCompanionNameTimestamp); + data << int32(BattlePetCompanionExperience); } if (changesMask[115]) { - data << int32(ViewerDependentValue::GetValue(this, owner, receiver)); + data << uint32(BattlePetCompanionNameTimestamp); } if (changesMask[116]) { - data << int32(ScaleDuration); + data << int32(ViewerDependentValue::GetValue(this, owner, receiver)); } if (changesMask[117]) { - data << int32(LooksLikeMountID); + data << int32(ScaleDuration); } if (changesMask[118]) { - data << int32(LooksLikeCreatureID); + data << int32(LooksLikeMountID); } if (changesMask[119]) { - data << int32(LookAtControllerID); + data << int32(LooksLikeCreatureID); } if (changesMask[120]) { - data << int32(PerksVendorItemID); + data << int32(LookAtControllerID); } if (changesMask[121]) { - data << int32(TaxiNodesID); + data << int32(PerksVendorItemID); } if (changesMask[122]) { - data << GuildGUID; + data << int32(TaxiNodesID); } if (changesMask[123]) { - data << int32(FlightCapabilityID); + data << GuildGUID; } if (changesMask[124]) { - data << float(GlideEventSpeedDivisor); + data << int32(FlightCapabilityID); } if (changesMask[125]) { - data << int32(MaxHealthModifierFlatNeg); + data << float(GlideEventSpeedDivisor); } if (changesMask[126]) { - data << int32(MaxHealthModifierFlatPos); + data << int32(DriveCapabilityID); } if (changesMask[127]) { - data << uint32(SilencedSchoolMask); + data << int32(MaxHealthModifierFlatNeg); } } if (changesMask[128]) { if (changesMask[129]) { - data << uint32(CurrentAreaID); + data << int32(MaxHealthModifierFlatPos); } if (changesMask[130]) { - data << float(Field_31C); + data << uint32(SilencedSchoolMask); } if (changesMask[131]) { - data << float(Field_320); + data << uint32(CurrentAreaID); } if (changesMask[132]) + { + data << float(Field_31C); + } + if (changesMask[133]) + { + data << float(Field_320); + } + if (changesMask[134]) { data << NameplateAttachToGUID; } } - if (changesMask[133]) + if (changesMask[135]) { for (uint32 i = 0; i < 10; ++i) { - if (changesMask[134 + i]) + if (changesMask[136 + i]) { data << int32(Power[i]); } - if (changesMask[144 + i]) + if (changesMask[146 + i]) { data << int32(MaxPower[i]); } - if (changesMask[154 + i]) + if (changesMask[156 + i]) { data << float(PowerRegenFlatModifier[i]); } - if (changesMask[164 + i]) + if (changesMask[166 + i]) { data << float(PowerRegenInterruptedFlatModifier[i]); } } } - if (changesMask[174]) + if (changesMask[176]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[175 + i]) + if (changesMask[177 + i]) { VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[178]) + if (changesMask[180]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[179 + i]) + if (changesMask[181 + i]) { data << uint32(AttackRoundBaseTime[i]); } } } - if (changesMask[181]) + if (changesMask[183]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[182 + i]) + if (changesMask[184 + i]) { data << int32(Stats[i]); } - if (changesMask[186 + i]) + if (changesMask[188 + i]) { data << int32(StatPosBuff[i]); } - if (changesMask[190 + i]) + if (changesMask[192 + i]) { data << int32(StatNegBuff[i]); } - if (changesMask[194 + i]) + if (changesMask[196 + i]) { data << int32(StatSupportBuff[i]); } } } - if (changesMask[198]) + if (changesMask[200]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[199 + i]) + if (changesMask[201 + i]) { data << int32(Resistances[i]); } - if (changesMask[206 + i]) + if (changesMask[208 + i]) { data << int32(BonusResistanceMods[i]); } - if (changesMask[213 + i]) + if (changesMask[215 + i]) { data << int32(ManaCostModifier[i]); } @@ -1884,6 +1895,7 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(Flags); Base::ClearChangesMask(Flags2); Base::ClearChangesMask(Flags3); + Base::ClearChangesMask(Flags4); Base::ClearChangesMask(AuraState); Base::ClearChangesMask(RangedAttackRoundBaseTime); Base::ClearChangesMask(BoundingRadius); @@ -1959,6 +1971,7 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(GuildGUID); Base::ClearChangesMask(FlightCapabilityID); Base::ClearChangesMask(GlideEventSpeedDivisor); + Base::ClearChangesMask(DriveCapabilityID); Base::ClearChangesMask(MaxHealthModifierFlatNeg); Base::ClearChangesMask(MaxHealthModifierFlatPos); Base::ClearChangesMask(SilencedSchoolMask); @@ -2205,15 +2218,15 @@ void PetCreatureName::ClearChangesMask() void CTROptions::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { - data << int32(ConditionalFlags); - data << uint32(FactionGroup); + data << uint32(ConditionalFlags); + data << uint8(FactionGroup); data << uint32(ChromieTimeExpansionMask); } void CTROptions::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - data << int32(ConditionalFlags); - data << uint32(FactionGroup); + data << uint32(ConditionalFlags); + data << uint8(FactionGroup); data << uint32(ChromieTimeExpansionMask); } @@ -4367,6 +4380,7 @@ void StablePetInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player co data << uint32(DisplayID); data << uint32(ExperienceLevel); data << uint8(PetFlags); + data << uint32(Specialization); data.WriteBits(Name->size(), 8); data.WriteString(Name); data.FlushBits(); @@ -4378,7 +4392,7 @@ void StablePetInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player if (ignoreChangesMask) changesMask.SetAll(); - data.WriteBits(changesMask.GetBlock(0), 8); + data.WriteBits(changesMask.GetBlock(0), 9); data.FlushBits(); if (changesMask[0]) @@ -4407,6 +4421,10 @@ void StablePetInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player { data << uint8(PetFlags); } + if (changesMask[8]) + { + data << uint32(Specialization); + } if (changesMask[6]) { data.WriteBits(Name->size(), 8); @@ -4425,6 +4443,7 @@ void StablePetInfo::ClearChangesMask() Base::ClearChangesMask(ExperienceLevel); Base::ClearChangesMask(Name); Base::ClearChangesMask(PetFlags); + Base::ClearChangesMask(Specialization); _changesMask.ResetAll(); } @@ -4741,7 +4760,7 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag f data << uint8(MultiActionBars); data << uint8(LifetimeMaxRank); data << uint8(NumRespecs); - data << uint32(PvpMedals); + data << uint8(PvpMedals); for (uint32 i = 0; i < 12; ++i) { data << uint32(BuybackPrice[i]); @@ -4826,6 +4845,7 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag f data << uint32(SelfResSpells.size()); data << uint32(RuneforgePowers.size()); data << uint32(TransmogIllusions.size()); + data << uint32(WarbandScenes.size()); data << uint32(CharacterRestrictions.size()); data << uint32(SpellPctModByLabel.size()); data << uint32(SpellFlatModByLabel.size()); @@ -4907,6 +4927,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag f { data << uint32(TransmogIllusions[i]); } + for (uint32 i = 0; i < WarbandScenes.size(); ++i) + { + data << uint32(WarbandScenes[i]); + } for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) { SpellPctModByLabel[i].WriteCreate(data, owner, receiver); @@ -5092,11 +5116,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data); } } - if (changesMask[40]) + if (changesMask[41]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[41]) + if (changesMask[42]) { if (!ignoreNestedChangesMask) ResearchSites[i].WriteUpdateMask(data); @@ -5105,11 +5129,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[42]) + if (changesMask[43]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[43]) + if (changesMask[44]) { if (!ignoreNestedChangesMask) ResearchSiteProgress[i].WriteUpdateMask(data); @@ -5118,11 +5142,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[44]) + if (changesMask[45]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[45]) + if (changesMask[46]) { if (!ignoreNestedChangesMask) Research[i].WriteUpdateMask(data); @@ -5131,11 +5155,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[40]) + if (changesMask[41]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[41]) + if (changesMask[42]) { for (uint32 j = 0; j < ResearchSites[i].size(); ++j) { @@ -5147,11 +5171,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[42]) + if (changesMask[43]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[43]) + if (changesMask[44]) { for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) { @@ -5163,11 +5187,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[44]) + if (changesMask[45]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[45]) + if (changesMask[46]) { for (uint32 j = 0; j < Research[i].size(); ++j) { @@ -5260,114 +5284,121 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.size(), data); } if (changesMask[22]) + { + if (!ignoreNestedChangesMask) + WarbandScenes.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WarbandScenes.size(), data); + } + if (changesMask[23]) { if (!ignoreNestedChangesMask) CharacterRestrictions.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data); } - if (changesMask[23]) + if (changesMask[24]) { if (!ignoreNestedChangesMask) SpellPctModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data); } - if (changesMask[24]) + if (changesMask[25]) { if (!ignoreNestedChangesMask) SpellFlatModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data); } - if (changesMask[25]) + if (changesMask[26]) { if (!ignoreNestedChangesMask) MawPowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MawPowers.size(), data); } - if (changesMask[26]) + if (changesMask[27]) { if (!ignoreNestedChangesMask) MultiFloorExploration.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.size(), data); } - if (changesMask[27]) + if (changesMask[28]) { if (!ignoreNestedChangesMask) RecipeProgression.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(RecipeProgression.size(), data); } - if (changesMask[28]) + if (changesMask[29]) { if (!ignoreNestedChangesMask) ReplayedQuests.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data); } - if (changesMask[29]) + if (changesMask[30]) { if (!ignoreNestedChangesMask) TaskQuests.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(TaskQuests.size(), data); } - if (changesMask[30]) + if (changesMask[31]) { if (!ignoreNestedChangesMask) DisabledSpells.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data); } - if (changesMask[31]) + } + if (changesMask[32]) + { + if (changesMask[33]) { if (!ignoreNestedChangesMask) TraitConfigs.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(TraitConfigs.size(), data); } - } - if (changesMask[32]) - { - if (changesMask[33]) + if (changesMask[34]) { if (!ignoreNestedChangesMask) CraftingOrders.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data); } - if (changesMask[34]) + if (changesMask[35]) { if (!ignoreNestedChangesMask) PersonalCraftingOrderCounts.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(PersonalCraftingOrderCounts.size(), data); } - if (changesMask[35]) + if (changesMask[36]) { if (!ignoreNestedChangesMask) NpcCraftingOrders.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(NpcCraftingOrders.size(), data); } - if (changesMask[36]) + if (changesMask[37]) { if (!ignoreNestedChangesMask) CategoryCooldownMods.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data); } - if (changesMask[37]) + if (changesMask[38]) { if (!ignoreNestedChangesMask) WeeklySpellUses.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data); } - if (changesMask[38]) + if (changesMask[39]) { if (!ignoreNestedChangesMask) TrackedCollectableSources.WriteUpdateMask(data); @@ -5498,7 +5529,17 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[23]) + if (changesMask[22]) + { + for (uint32 i = 0; i < WarbandScenes.size(); ++i) + { + if (WarbandScenes.HasChanged(i) || ignoreNestedChangesMask) + { + data << uint32(WarbandScenes[i]); + } + } + } + if (changesMask[24]) { for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) { @@ -5508,7 +5549,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[24]) + if (changesMask[25]) { for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) { @@ -5518,7 +5559,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[25]) + if (changesMask[26]) { for (uint32 i = 0; i < MawPowers.size(); ++i) { @@ -5528,7 +5569,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[26]) + if (changesMask[27]) { for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) { @@ -5538,7 +5579,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[27]) + if (changesMask[28]) { for (uint32 i = 0; i < RecipeProgression.size(); ++i) { @@ -5548,7 +5589,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[28]) + if (changesMask[29]) { for (uint32 i = 0; i < ReplayedQuests.size(); ++i) { @@ -5558,7 +5599,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[29]) + if (changesMask[30]) { for (uint32 i = 0; i < TaskQuests.size(); ++i) { @@ -5568,7 +5609,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[30]) + if (changesMask[31]) { for (uint32 i = 0; i < DisabledSpells.size(); ++i) { @@ -5581,7 +5622,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } if (changesMask[32]) { - if (changesMask[34]) + if (changesMask[35]) { for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) { @@ -5591,7 +5632,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[35]) + if (changesMask[36]) { for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i) { @@ -5601,7 +5642,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[36]) + if (changesMask[37]) { for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) { @@ -5611,7 +5652,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[37]) + if (changesMask[38]) { for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) { @@ -5621,7 +5662,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[38]) + if (changesMask[39]) { for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) { @@ -5631,7 +5672,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[39]) + if (changesMask[40]) { if (!ignoreNestedChangesMask) AccountBankTabSettings.WriteUpdateMask(data, 3); @@ -5671,7 +5712,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[22]) + if (changesMask[23]) { for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) { @@ -5681,7 +5722,10 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[31]) + } + if (changesMask[32]) + { + if (changesMask[33]) { for (uint32 i = 0; i < TraitConfigs.size(); ++i) { @@ -5691,10 +5735,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - } - if (changesMask[32]) - { - if (changesMask[33]) + if (changesMask[34]) { for (uint32 i = 0; i < CraftingOrders.size(); ++i) { @@ -5704,7 +5745,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[39]) + if (changesMask[40]) { for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) { @@ -5714,364 +5755,364 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[46]) - { - data << FarsightObject; - } if (changesMask[47]) { - data << SummonedBattlePetGUID; + data << FarsightObject; } if (changesMask[48]) { - data << uint64(Coinage); + data << SummonedBattlePetGUID; } if (changesMask[49]) { - data << uint64(AccountBankCoinage); + data << uint64(Coinage); } if (changesMask[50]) { - data << int32(XP); + data << uint64(AccountBankCoinage); } if (changesMask[51]) { - data << int32(NextLevelXP); + data << int32(XP); } if (changesMask[52]) { - data << int32(TrialXP); + data << int32(NextLevelXP); } if (changesMask[53]) { - Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << int32(TrialXP); } if (changesMask[54]) { - data << int32(CharacterPoints); + Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[55]) { - data << int32(MaxTalentTiers); + data << int32(CharacterPoints); } if (changesMask[56]) { - data << uint32(TrackCreatureMask); + data << int32(MaxTalentTiers); } if (changesMask[57]) { - data << float(MainhandExpertise); + data << uint32(TrackCreatureMask); } if (changesMask[58]) { - data << float(OffhandExpertise); + data << float(MainhandExpertise); } if (changesMask[59]) { - data << float(RangedExpertise); + data << float(OffhandExpertise); } if (changesMask[60]) { - data << float(CombatRatingExpertise); + data << float(RangedExpertise); } if (changesMask[61]) { - data << float(BlockPercentage); + data << float(CombatRatingExpertise); } if (changesMask[62]) { - data << float(DodgePercentage); + data << float(BlockPercentage); } if (changesMask[63]) { - data << float(DodgePercentageFromAttribute); + data << float(DodgePercentage); } if (changesMask[64]) { - data << float(ParryPercentage); + data << float(DodgePercentageFromAttribute); } if (changesMask[65]) { - data << float(ParryPercentageFromAttribute); + data << float(ParryPercentage); } if (changesMask[66]) { - data << float(CritPercentage); + data << float(ParryPercentageFromAttribute); } if (changesMask[67]) { - data << float(RangedCritPercentage); + data << float(CritPercentage); } if (changesMask[68]) { - data << float(OffhandCritPercentage); + data << float(RangedCritPercentage); } if (changesMask[69]) { - data << float(SpellCritPercentage); + data << float(OffhandCritPercentage); } } if (changesMask[70]) { if (changesMask[71]) { - data << int32(ShieldBlock); + data << float(SpellCritPercentage); } if (changesMask[72]) { - data << float(ShieldBlockCritPercentage); + data << int32(ShieldBlock); } if (changesMask[73]) { - data << float(Mastery); + data << float(ShieldBlockCritPercentage); } if (changesMask[74]) { - data << float(Speed); + data << float(Mastery); } if (changesMask[75]) { - data << float(Avoidance); + data << float(Speed); } if (changesMask[76]) { - data << float(Sturdiness); + data << float(Avoidance); } if (changesMask[77]) { - data << int32(Versatility); + data << float(Sturdiness); } if (changesMask[78]) { - data << float(VersatilityBonus); + data << int32(Versatility); } if (changesMask[79]) { - data << float(PvpPowerDamage); + data << float(VersatilityBonus); } if (changesMask[80]) { - data << float(PvpPowerHealing); + data << float(PvpPowerDamage); } if (changesMask[81]) { - BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << float(PvpPowerHealing); } if (changesMask[82]) { - data << int32(ModHealingDonePos); + BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[83]) { - data << float(ModHealingPercent); + data << int32(ModHealingDonePos); } if (changesMask[84]) { - data << float(ModPeriodicHealingDonePercent); + data << float(ModHealingPercent); } if (changesMask[85]) { - data << float(ModSpellPowerPercent); + data << float(ModPeriodicHealingDonePercent); } if (changesMask[86]) { - data << float(ModResiliencePercent); + data << float(ModSpellPowerPercent); } if (changesMask[87]) { - data << float(OverrideSpellPowerByAPPercent); + data << float(ModResiliencePercent); } if (changesMask[88]) { - data << float(OverrideAPBySpellPowerPercent); + data << float(OverrideSpellPowerByAPPercent); } if (changesMask[89]) { - data << int32(ModTargetResistance); + data << float(OverrideAPBySpellPowerPercent); } if (changesMask[90]) { - data << int32(ModTargetPhysicalResistance); + data << int32(ModTargetResistance); } if (changesMask[91]) { - data << uint32(LocalFlags); + data << int32(ModTargetPhysicalResistance); } if (changesMask[92]) { - data << uint8(GrantableLevels); + data << uint32(LocalFlags); } if (changesMask[93]) { - data << uint8(MultiActionBars); + data << uint8(GrantableLevels); } if (changesMask[94]) { - data << uint8(LifetimeMaxRank); + data << uint8(MultiActionBars); } if (changesMask[95]) { - data << uint8(NumRespecs); + data << uint8(LifetimeMaxRank); } if (changesMask[96]) { - data << uint32(PvpMedals); + data << uint8(NumRespecs); } if (changesMask[97]) { - data << uint16(TodayHonorableKills); + data << uint8(PvpMedals); } if (changesMask[98]) { - data << uint16(YesterdayHonorableKills); + data << uint16(TodayHonorableKills); } if (changesMask[99]) { - data << uint32(LifetimeHonorableKills); + data << uint16(YesterdayHonorableKills); } if (changesMask[100]) { - data << int32(WatchedFactionIndex); + data << uint32(LifetimeHonorableKills); } if (changesMask[101]) { - data << int32(MaxLevel); + data << int32(WatchedFactionIndex); } } if (changesMask[102]) { if (changesMask[103]) { - data << int32(ScalingPlayerLevelDelta); + data << int32(MaxLevel); } if (changesMask[104]) { - data << int32(MaxCreatureScalingLevel); + data << int32(ScalingPlayerLevelDelta); } if (changesMask[105]) { - data << int32(PetSpellPower); + data << int32(MaxCreatureScalingLevel); } if (changesMask[106]) { - data << float(UiHitModifier); + data << int32(PetSpellPower); } if (changesMask[107]) { - data << float(UiSpellHitModifier); + data << float(UiHitModifier); } if (changesMask[108]) { - data << int32(HomeRealmTimeOffset); + data << float(UiSpellHitModifier); } if (changesMask[109]) { - data << float(ModPetHaste); + data << int32(HomeRealmTimeOffset); } if (changesMask[110]) { - data << int8(JailersTowerLevelMax); + data << float(ModPetHaste); } if (changesMask[111]) { - data << int8(JailersTowerLevel); + data << int8(JailersTowerLevelMax); } if (changesMask[112]) { - data << uint8(LocalRegenFlags); + data << int8(JailersTowerLevel); } if (changesMask[113]) { - data << uint8(AuraVision); + data << uint8(LocalRegenFlags); } if (changesMask[114]) { - data << uint8(NumBackpackSlots); + data << uint8(AuraVision); } if (changesMask[115]) { - data << int32(OverrideSpellsID); + data << uint8(NumBackpackSlots); } if (changesMask[116]) { - data << uint16(LootSpecID); + data << int32(OverrideSpellsID); } if (changesMask[117]) { - data << uint32(OverrideZonePVPType); + data << uint16(LootSpecID); } if (changesMask[118]) { - data << int32(Honor); + data << uint32(OverrideZonePVPType); } if (changesMask[119]) { - data << int32(HonorNextLevel); + data << int32(Honor); } if (changesMask[120]) { - data << int32(PerksProgramCurrency); + data << int32(HonorNextLevel); } if (changesMask[121]) { - data << uint8(NumBankSlots); + data << int32(PerksProgramCurrency); } if (changesMask[122]) { - data << uint8(NumAccountBankTabs); + data << uint8(NumBankSlots); } - if (changesMask[127]) + if (changesMask[123]) { - data << int32(UiChromieTimeExpansionID); + data << uint8(NumAccountBankTabs); } if (changesMask[128]) { - data << int32(TimerunningSeasonID); + data << int32(UiChromieTimeExpansionID); } if (changesMask[129]) { - data << int32(TransportServerTime); + data << int32(TimerunningSeasonID); } if (changesMask[130]) { - data << uint32(WeeklyRewardsPeriodSinceOrigin); + data << int32(TransportServerTime); } if (changesMask[131]) { - data << int16(DEBUGSoulbindConduitRank); + data << uint32(WeeklyRewardsPeriodSinceOrigin); } - if (changesMask[133]) + if (changesMask[132]) { - data << uint32(ActiveCombatTraitConfigID); + data << int16(DEBUGSoulbindConduitRank); } } if (changesMask[134]) { if (changesMask[135]) { - data << int32(ItemUpgradeHighOnehandWeaponItemID); + data << uint32(ActiveCombatTraitConfigID); } if (changesMask[136]) { - data << int32(ItemUpgradeHighFingerItemID); + data << int32(ItemUpgradeHighOnehandWeaponItemID); } if (changesMask[137]) { - data << float(ItemUpgradeHighFingerWatermark); + data << int32(ItemUpgradeHighFingerItemID); } if (changesMask[138]) { - data << int32(ItemUpgradeHighTrinketItemID); + data << float(ItemUpgradeHighFingerWatermark); } if (changesMask[139]) { - data << float(ItemUpgradeHighTrinketWatermark); + data << int32(ItemUpgradeHighTrinketItemID); } if (changesMask[140]) + { + data << float(ItemUpgradeHighTrinketWatermark); + } + if (changesMask[141]) { data << uint64(LootHistoryInstanceID); } - if (changesMask[142]) + if (changesMask[143]) { data << uint8(RequiredMountCapabilityFlags); } @@ -6089,47 +6130,47 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo data.FlushBits(); if (changesMask[102]) { - if (changesMask[123]) + if (changesMask[124]) { ResearchHistory->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[125]) + if (changesMask[126]) { if (QuestSession.has_value()) { QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[124]) + if (changesMask[125]) { data << FrozenPerksVendorItem; } - if (changesMask[126]) + if (changesMask[127]) { Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[132]) + if (changesMask[133]) { data << DungeonScore; } } if (changesMask[134]) { - if (changesMask[141]) + if (changesMask[142]) { if (PetStable.has_value()) { PetStable->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[143]) + if (changesMask[144]) { if (WalkInData.has_value()) { WalkInData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[144]) + if (changesMask[145]) { if (DelveData.has_value()) { @@ -6137,141 +6178,141 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[145]) + if (changesMask[146]) { for (uint32 i = 0; i < 232; ++i) { - if (changesMask[146 + i]) + if (changesMask[147 + i]) { data << InvSlots[i]; } } } - if (changesMask[378]) + if (changesMask[379]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[379 + i]) + if (changesMask[380 + i]) { RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[381]) + if (changesMask[382]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[382 + i]) + if (changesMask[383 + i]) { data << int32(ModDamageDonePos[i]); } - if (changesMask[389 + i]) + if (changesMask[390 + i]) { data << int32(ModDamageDoneNeg[i]); } - if (changesMask[396 + i]) + if (changesMask[397 + i]) { data << float(ModDamageDonePercent[i]); } - if (changesMask[403 + i]) + if (changesMask[404 + i]) { data << float(ModHealingDonePercent[i]); } } } - if (changesMask[410]) + if (changesMask[411]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[411 + i]) + if (changesMask[412 + i]) { data << float(WeaponDmgMultipliers[i]); } - if (changesMask[414 + i]) + if (changesMask[415 + i]) { data << float(WeaponAtkSpeedMultipliers[i]); } } } - if (changesMask[417]) + if (changesMask[418]) { for (uint32 i = 0; i < 12; ++i) { - if (changesMask[418 + i]) + if (changesMask[419 + i]) { data << uint32(BuybackPrice[i]); } - if (changesMask[430 + i]) + if (changesMask[431 + i]) { data << int64(BuybackTimestamp[i]); } } } - if (changesMask[442]) + if (changesMask[443]) { for (uint32 i = 0; i < 32; ++i) { - if (changesMask[443 + i]) + if (changesMask[444 + i]) { data << int32(CombatRatings[i]); } } } - if (changesMask[475]) + if (changesMask[476]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[476 + i]) + if (changesMask[477 + i]) { data << uint32(NoReagentCostMask[i]); } } } - if (changesMask[480]) + if (changesMask[481]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[481 + i]) + if (changesMask[482 + i]) { data << int32(ProfessionSkillLine[i]); } } } - if (changesMask[483]) + if (changesMask[484]) { for (uint32 i = 0; i < 5; ++i) { - if (changesMask[484 + i]) + if (changesMask[485 + i]) { data << uint32(BagSlotFlags[i]); } } } - if (changesMask[489]) + if (changesMask[490]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[490 + i]) + if (changesMask[491 + i]) { data << uint32(BankBagSlotFlags[i]); } } } - if (changesMask[497]) + if (changesMask[498]) { for (uint32 i = 0; i < 1000; ++i) { - if (changesMask[498 + i]) + if (changesMask[499 + i]) { data << uint64(QuestCompleted[i]); } } } - if (changesMask[1498]) + if (changesMask[1499]) { for (uint32 i = 0; i < 17; ++i) { - if (changesMask[1499 + i]) + if (changesMask[1500 + i]) { data << float(ItemUpgradeHighWatermark[i]); } @@ -6303,6 +6344,7 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(SelfResSpells); Base::ClearChangesMask(RuneforgePowers); Base::ClearChangesMask(TransmogIllusions); + Base::ClearChangesMask(WarbandScenes); Base::ClearChangesMask(SpellPctModByLabel); Base::ClearChangesMask(SpellFlatModByLabel); Base::ClearChangesMask(MawPowers); @@ -6441,13 +6483,14 @@ void ActivePlayerData::ClearChangesMask() void GameObjectData::WriteCreate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const { - ViewerDependentValue::value_type stateWorldEffectIDs = ViewerDependentValue::GetValue(this, owner, receiver); + ViewerDependentValue::value_type stateWorldEffectIDs = {}; data << int32(DisplayID); data << uint32(SpellVisualID); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); data << uint32(ViewerDependentValue::GetValue(this, owner, receiver)); + stateWorldEffectIDs = ViewerDependentValue::GetValue(this, owner, receiver); data << uint32(stateWorldEffectIDs->size()); data << uint32(StateWorldEffectsQuestObjectiveID); for (uint32 i = 0; i < stateWorldEffectIDs->size(); ++i) diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 0f24599e5db..bc02576f7f6 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -258,7 +258,7 @@ struct PassiveSpellHistory : public IsUpdateFieldStructureTag bool operator!=(PassiveSpellHistory const& right) const { return !(*this == right); } }; -struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<220> +struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<222> { UpdateField Field_314; UpdateField, 0, 2> StateWorldEffectIDs; @@ -308,7 +308,7 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<220> UpdateField ScalingLevelMin; UpdateField ScalingLevelMax; UpdateField ScalingLevelDelta; - UpdateField ScalingFactionGroup; + UpdateField ScalingFactionGroup; UpdateField FactionTemplate; struct FactionTemplateTag : ViewerDependentValueTag {}; UpdateField Flags; @@ -317,104 +317,107 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<220> struct Flags2Tag : ViewerDependentValueTag {}; UpdateField Flags3; struct Flags3Tag : ViewerDependentValueTag {}; - UpdateField AuraState; + UpdateField Flags4; + struct Flags4Tag : ViewerDependentValueTag {}; + UpdateField AuraState; struct AuraStateTag : ViewerDependentValueTag {}; - UpdateField RangedAttackRoundBaseTime; - UpdateField BoundingRadius; - UpdateField CombatReach; - UpdateField DisplayScale; - UpdateField CreatureFamily; - UpdateField CreatureType; - UpdateField NativeDisplayID; - UpdateField NativeXDisplayScale; - UpdateField MountDisplayID; - UpdateField CosmeticMountDisplayID; - UpdateField MinDamage; - UpdateField MaxDamage; - UpdateField MinOffHandDamage; - UpdateField MaxOffHandDamage; - UpdateField StandState; - UpdateField PetTalentPoints; - UpdateField VisFlags; - UpdateField AnimTier; - UpdateField PetNumber; - UpdateField PetNameTimestamp; - UpdateField PetExperience; - UpdateField PetNextLevelExperience; - UpdateField ModCastingSpeed; - UpdateField ModCastingSpeedNeg; - UpdateField ModSpellHaste; - UpdateField ModHaste; - UpdateField ModRangedHaste; - UpdateField ModHasteRegen; - UpdateField ModTimeRate; - UpdateField CreatedBySpell; - UpdateField EmoteState; - UpdateField BaseMana; - UpdateField BaseHealth; - UpdateField SheatheState; - UpdateField PvpFlags; + UpdateField RangedAttackRoundBaseTime; + UpdateField BoundingRadius; + UpdateField CombatReach; + UpdateField DisplayScale; + UpdateField CreatureFamily; + UpdateField CreatureType; + UpdateField NativeDisplayID; + UpdateField NativeXDisplayScale; + UpdateField MountDisplayID; + UpdateField CosmeticMountDisplayID; + UpdateField MinDamage; + UpdateField MaxDamage; + UpdateField MinOffHandDamage; + UpdateField MaxOffHandDamage; + UpdateField StandState; + UpdateField PetTalentPoints; + UpdateField VisFlags; + UpdateField AnimTier; + UpdateField PetNumber; + UpdateField PetNameTimestamp; + UpdateField PetExperience; + UpdateField PetNextLevelExperience; + UpdateField ModCastingSpeed; + UpdateField ModCastingSpeedNeg; + UpdateField ModSpellHaste; + UpdateField ModHaste; + UpdateField ModRangedHaste; + UpdateField ModHasteRegen; + UpdateField ModTimeRate; + UpdateField CreatedBySpell; + UpdateField EmoteState; + UpdateField BaseMana; + UpdateField BaseHealth; + UpdateField SheatheState; + UpdateField PvpFlags; struct PvpFlagsTag : ViewerDependentValueTag {}; - UpdateField PetFlags; - UpdateField ShapeshiftForm; - UpdateField AttackPower; - UpdateField AttackPowerModPos; - UpdateField AttackPowerModNeg; - UpdateField AttackPowerMultiplier; - UpdateField AttackPowerModSupport; - UpdateField RangedAttackPower; - UpdateField RangedAttackPowerModPos; - UpdateField RangedAttackPowerModNeg; - UpdateField RangedAttackPowerMultiplier; - UpdateField RangedAttackPowerModSupport; - UpdateField MainHandWeaponAttackPower; - UpdateField OffHandWeaponAttackPower; - UpdateField RangedWeaponAttackPower; - UpdateField SetAttackSpeedAura; - UpdateField Lifesteal; - UpdateField MinRangedDamage; - UpdateField MaxRangedDamage; - UpdateField ManaCostMultiplier; - UpdateField MaxHealthModifier; - UpdateField HoverHeight; - UpdateField MinItemLevelCutoff; - UpdateField MinItemLevel; - UpdateField MaxItemLevel; - UpdateField AzeriteItemLevel; - UpdateField WildBattlePetLevel; - UpdateField BattlePetCompanionExperience; - UpdateField BattlePetCompanionNameTimestamp; - UpdateField InteractSpellID; + UpdateField PetFlags; + UpdateField ShapeshiftForm; + UpdateField AttackPower; + UpdateField AttackPowerModPos; + UpdateField AttackPowerModNeg; + UpdateField AttackPowerMultiplier; + UpdateField AttackPowerModSupport; + UpdateField RangedAttackPower; + UpdateField RangedAttackPowerModPos; + UpdateField RangedAttackPowerModNeg; + UpdateField RangedAttackPowerMultiplier; + UpdateField RangedAttackPowerModSupport; + UpdateField MainHandWeaponAttackPower; + UpdateField OffHandWeaponAttackPower; + UpdateField RangedWeaponAttackPower; + UpdateField SetAttackSpeedAura; + UpdateField Lifesteal; + UpdateField MinRangedDamage; + UpdateField MaxRangedDamage; + UpdateField ManaCostMultiplier; + UpdateField MaxHealthModifier; + UpdateField HoverHeight; + UpdateField MinItemLevelCutoff; + UpdateField MinItemLevel; + UpdateField MaxItemLevel; + UpdateField AzeriteItemLevel; + UpdateField WildBattlePetLevel; + UpdateField BattlePetCompanionExperience; + UpdateField BattlePetCompanionNameTimestamp; + UpdateField InteractSpellID; struct InteractSpellIDTag : ViewerDependentValueTag {}; - UpdateField ScaleDuration; - UpdateField LooksLikeMountID; - UpdateField LooksLikeCreatureID; - UpdateField LookAtControllerID; - UpdateField PerksVendorItemID; - UpdateField TaxiNodesID; - UpdateField GuildGUID; - UpdateField FlightCapabilityID; - UpdateField GlideEventSpeedDivisor; // Movement speed gets divided by this value when evaluating what GlideEvents to use - UpdateField MaxHealthModifierFlatNeg; - UpdateField MaxHealthModifierFlatPos; - UpdateField SilencedSchoolMask; - UpdateField CurrentAreaID; - UpdateField Field_31C; - UpdateField Field_320; // Soft targeting related? When UnitFlags3 & 0x40000000 is set, increases some range check using CombatReach by this amount - UpdateField NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object - UpdateFieldArray Power; - UpdateFieldArray MaxPower; - UpdateFieldArray PowerRegenFlatModifier; - UpdateFieldArray PowerRegenInterruptedFlatModifier; - UpdateFieldArray VirtualItems; - UpdateFieldArray AttackRoundBaseTime; - UpdateFieldArray Stats; - UpdateFieldArray StatPosBuff; - UpdateFieldArray StatNegBuff; - UpdateFieldArray StatSupportBuff; - UpdateFieldArray Resistances; - UpdateFieldArray BonusResistanceMods; - UpdateFieldArray ManaCostModifier; + UpdateField ScaleDuration; + UpdateField LooksLikeMountID; + UpdateField LooksLikeCreatureID; + UpdateField LookAtControllerID; + UpdateField PerksVendorItemID; + UpdateField TaxiNodesID; + UpdateField GuildGUID; + UpdateField FlightCapabilityID; + UpdateField GlideEventSpeedDivisor; // Movement speed gets divided by this value when evaluating what GlideEvents to use + UpdateField DriveCapabilityID; + UpdateField MaxHealthModifierFlatNeg; + UpdateField MaxHealthModifierFlatPos; + UpdateField SilencedSchoolMask; + UpdateField CurrentAreaID; + UpdateField Field_31C; + UpdateField Field_320; // Soft targeting related? When UnitFlags3 & 0x40000000 is set, increases some range check using CombatReach by this amount + UpdateField NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object + UpdateFieldArray Power; + UpdateFieldArray MaxPower; + UpdateFieldArray PowerRegenFlatModifier; + UpdateFieldArray PowerRegenInterruptedFlatModifier; + UpdateFieldArray VirtualItems; + UpdateFieldArray AttackRoundBaseTime; + UpdateFieldArray Stats; + UpdateFieldArray StatPosBuff; + UpdateFieldArray StatNegBuff; + UpdateFieldArray StatSupportBuff; + UpdateFieldArray Resistances; + UpdateFieldArray BonusResistanceMods; + UpdateFieldArray ManaCostModifier; void WriteCreate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; @@ -485,8 +488,8 @@ struct PetCreatureName : public IsUpdateFieldStructureTag, public HasChangesMask struct CTROptions : public IsUpdateFieldStructureTag { - int32 ConditionalFlags; - uint32 FactionGroup; + uint32 ConditionalFlags; + uint8 FactionGroup; uint32 ChromieTimeExpansionMask; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; @@ -944,7 +947,7 @@ struct WeeklySpellUse : public IsUpdateFieldStructureTag bool operator!=(WeeklySpellUse const& right) const { return !(*this == right); } }; -struct StablePetInfo : public IsUpdateFieldStructureTag, public HasChangesMask<8> +struct StablePetInfo : public IsUpdateFieldStructureTag, public HasChangesMask<9> { UpdateField PetSlot; UpdateField PetNumber; @@ -953,6 +956,7 @@ struct StablePetInfo : public IsUpdateFieldStructureTag, public HasChangesMask<8 UpdateField ExperienceLevel; UpdateField Name; UpdateField PetFlags; + UpdateField Specialization; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; @@ -1030,7 +1034,7 @@ struct Research : public IsUpdateFieldStructureTag bool operator!=(Research const& right) const { return !(*this == right); } }; -struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1516> +struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1517> { UpdateField BackpackAutoSortDisabled; UpdateField BackpackSellJunkDisabled; @@ -1038,9 +1042,9 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas UpdateField SortBagsRightToLeft; UpdateField InsertItemsLeftToRight; UpdateField HasPerksProgramPendingReward; - UpdateFieldArray, 1, 40, 41> ResearchSites; - UpdateFieldArray, 1, 42, 43> ResearchSiteProgress; - UpdateFieldArray, 1, 44, 45> Research; + UpdateFieldArray, 1, 41, 42> ResearchSites; + UpdateFieldArray, 1, 43, 44> ResearchSiteProgress; + UpdateFieldArray, 1, 45, 46> Research; DynamicUpdateField KnownTitles; DynamicUpdateField DailyQuestsCompleted; DynamicUpdateField AvailableQuestLineXQuestIDs; @@ -1053,139 +1057,140 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas DynamicUpdateField SelfResSpells; DynamicUpdateField RuneforgePowers; DynamicUpdateField TransmogIllusions; - DynamicUpdateField SpellPctModByLabel; - DynamicUpdateField SpellFlatModByLabel; - DynamicUpdateField MawPowers; - DynamicUpdateField MultiFloorExploration; - DynamicUpdateField RecipeProgression; - DynamicUpdateField ReplayedQuests; - DynamicUpdateField TaskQuests; - DynamicUpdateField DisabledSpells; - DynamicUpdateField PersonalCraftingOrderCounts; - DynamicUpdateField NpcCraftingOrders; - DynamicUpdateField CategoryCooldownMods; - DynamicUpdateField WeeklySpellUses; - DynamicUpdateField TrackedCollectableSources; + DynamicUpdateField WarbandScenes; + DynamicUpdateField SpellPctModByLabel; + DynamicUpdateField SpellFlatModByLabel; + DynamicUpdateField MawPowers; + DynamicUpdateField MultiFloorExploration; + DynamicUpdateField RecipeProgression; + DynamicUpdateField ReplayedQuests; + DynamicUpdateField TaskQuests; + DynamicUpdateField DisabledSpells; + DynamicUpdateField PersonalCraftingOrderCounts; + DynamicUpdateField NpcCraftingOrders; + DynamicUpdateField CategoryCooldownMods; + DynamicUpdateField WeeklySpellUses; + DynamicUpdateField TrackedCollectableSources; DynamicUpdateField CharacterDataElements; DynamicUpdateField AccountDataElements; DynamicUpdateField PvpInfo; - DynamicUpdateField CharacterRestrictions; - DynamicUpdateField TraitConfigs; - DynamicUpdateField CraftingOrders; - DynamicUpdateField AccountBankTabSettings; - UpdateField FarsightObject; - UpdateField SummonedBattlePetGUID; - UpdateField Coinage; - UpdateField AccountBankCoinage; - UpdateField XP; - UpdateField NextLevelXP; - UpdateField TrialXP; - UpdateField Skill; - UpdateField CharacterPoints; - UpdateField MaxTalentTiers; - UpdateField TrackCreatureMask; - UpdateField MainhandExpertise; - UpdateField OffhandExpertise; - UpdateField RangedExpertise; - UpdateField CombatRatingExpertise; - UpdateField BlockPercentage; - UpdateField DodgePercentage; - UpdateField DodgePercentageFromAttribute; - UpdateField ParryPercentage; - UpdateField ParryPercentageFromAttribute; - UpdateField CritPercentage; - UpdateField RangedCritPercentage; - UpdateField OffhandCritPercentage; - UpdateField SpellCritPercentage; - UpdateField ShieldBlock; - UpdateField ShieldBlockCritPercentage; - UpdateField Mastery; - UpdateField Speed; - UpdateField Avoidance; - UpdateField Sturdiness; - UpdateField Versatility; - UpdateField VersatilityBonus; - UpdateField PvpPowerDamage; - UpdateField PvpPowerHealing; - UpdateField BitVectors; - UpdateField ModHealingDonePos; - UpdateField ModHealingPercent; - UpdateField ModPeriodicHealingDonePercent; - UpdateField ModSpellPowerPercent; - UpdateField ModResiliencePercent; - UpdateField OverrideSpellPowerByAPPercent; - UpdateField OverrideAPBySpellPowerPercent; - UpdateField ModTargetResistance; - UpdateField ModTargetPhysicalResistance; - UpdateField LocalFlags; - UpdateField GrantableLevels; - UpdateField MultiActionBars; - UpdateField LifetimeMaxRank; - UpdateField NumRespecs; - UpdateField PvpMedals; - UpdateField TodayHonorableKills; - UpdateField YesterdayHonorableKills; - UpdateField LifetimeHonorableKills; - UpdateField WatchedFactionIndex; - UpdateField MaxLevel; - UpdateField ScalingPlayerLevelDelta; - UpdateField MaxCreatureScalingLevel; - UpdateField PetSpellPower; - UpdateField UiHitModifier; - UpdateField UiSpellHitModifier; - UpdateField HomeRealmTimeOffset; - UpdateField ModPetHaste; - UpdateField JailersTowerLevelMax; - UpdateField JailersTowerLevel; - UpdateField LocalRegenFlags; - UpdateField AuraVision; - UpdateField NumBackpackSlots; - UpdateField OverrideSpellsID; - UpdateField LootSpecID; - UpdateField OverrideZonePVPType; - UpdateField Honor; - UpdateField HonorNextLevel; - UpdateField PerksProgramCurrency; - UpdateField NumBankSlots; - UpdateField NumAccountBankTabs; - UpdateField ResearchHistory; - UpdateField FrozenPerksVendorItem; - UpdateField Field_1410; - OptionalUpdateField QuestSession; - UpdateField UiChromieTimeExpansionID; - UpdateField TimerunningSeasonID; - UpdateField TransportServerTime; - UpdateField WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin - UpdateField DEBUGSoulbindConduitRank; - UpdateField DungeonScore; - UpdateField ActiveCombatTraitConfigID; - UpdateField ItemUpgradeHighOnehandWeaponItemID; - UpdateField ItemUpgradeHighFingerItemID; - UpdateField ItemUpgradeHighFingerWatermark; - UpdateField ItemUpgradeHighTrinketItemID; - UpdateField ItemUpgradeHighTrinketWatermark; - UpdateField LootHistoryInstanceID; - OptionalUpdateField PetStable; - UpdateField RequiredMountCapabilityFlags; - OptionalUpdateField WalkInData; - OptionalUpdateField DelveData; - UpdateFieldArray InvSlots; - UpdateFieldArray RestInfo; - UpdateFieldArray ModDamageDonePos; - UpdateFieldArray ModDamageDoneNeg; - UpdateFieldArray ModDamageDonePercent; - UpdateFieldArray ModHealingDonePercent; - UpdateFieldArray WeaponDmgMultipliers; - UpdateFieldArray WeaponAtkSpeedMultipliers; - UpdateFieldArray BuybackPrice; - UpdateFieldArray BuybackTimestamp; - UpdateFieldArray CombatRatings; - UpdateFieldArray NoReagentCostMask; - UpdateFieldArray ProfessionSkillLine; - UpdateFieldArray BagSlotFlags; - UpdateFieldArray BankBagSlotFlags; - UpdateFieldArray QuestCompleted; - UpdateFieldArray ItemUpgradeHighWatermark; + DynamicUpdateField CharacterRestrictions; + DynamicUpdateField TraitConfigs; + DynamicUpdateField CraftingOrders; + DynamicUpdateField AccountBankTabSettings; + UpdateField FarsightObject; + UpdateField SummonedBattlePetGUID; + UpdateField Coinage; + UpdateField AccountBankCoinage; + UpdateField XP; + UpdateField NextLevelXP; + UpdateField TrialXP; + UpdateField Skill; + UpdateField CharacterPoints; + UpdateField MaxTalentTiers; + UpdateField TrackCreatureMask; + UpdateField MainhandExpertise; + UpdateField OffhandExpertise; + UpdateField RangedExpertise; + UpdateField CombatRatingExpertise; + UpdateField BlockPercentage; + UpdateField DodgePercentage; + UpdateField DodgePercentageFromAttribute; + UpdateField ParryPercentage; + UpdateField ParryPercentageFromAttribute; + UpdateField CritPercentage; + UpdateField RangedCritPercentage; + UpdateField OffhandCritPercentage; + UpdateField SpellCritPercentage; + UpdateField ShieldBlock; + UpdateField ShieldBlockCritPercentage; + UpdateField Mastery; + UpdateField Speed; + UpdateField Avoidance; + UpdateField Sturdiness; + UpdateField Versatility; + UpdateField VersatilityBonus; + UpdateField PvpPowerDamage; + UpdateField PvpPowerHealing; + UpdateField BitVectors; + UpdateField ModHealingDonePos; + UpdateField ModHealingPercent; + UpdateField ModPeriodicHealingDonePercent; + UpdateField ModSpellPowerPercent; + UpdateField ModResiliencePercent; + UpdateField OverrideSpellPowerByAPPercent; + UpdateField OverrideAPBySpellPowerPercent; + UpdateField ModTargetResistance; + UpdateField ModTargetPhysicalResistance; + UpdateField LocalFlags; + UpdateField GrantableLevels; + UpdateField MultiActionBars; + UpdateField LifetimeMaxRank; + UpdateField NumRespecs; + UpdateField PvpMedals; + UpdateField TodayHonorableKills; + UpdateField YesterdayHonorableKills; + UpdateField LifetimeHonorableKills; + UpdateField WatchedFactionIndex; + UpdateField MaxLevel; + UpdateField ScalingPlayerLevelDelta; + UpdateField MaxCreatureScalingLevel; + UpdateField PetSpellPower; + UpdateField UiHitModifier; + UpdateField UiSpellHitModifier; + UpdateField HomeRealmTimeOffset; + UpdateField ModPetHaste; + UpdateField JailersTowerLevelMax; + UpdateField JailersTowerLevel; + UpdateField LocalRegenFlags; + UpdateField AuraVision; + UpdateField NumBackpackSlots; + UpdateField OverrideSpellsID; + UpdateField LootSpecID; + UpdateField OverrideZonePVPType; + UpdateField Honor; + UpdateField HonorNextLevel; + UpdateField PerksProgramCurrency; + UpdateField NumBankSlots; + UpdateField NumAccountBankTabs; + UpdateField ResearchHistory; + UpdateField FrozenPerksVendorItem; + UpdateField Field_1410; + OptionalUpdateField QuestSession; + UpdateField UiChromieTimeExpansionID; + UpdateField TimerunningSeasonID; + UpdateField TransportServerTime; + UpdateField WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin + UpdateField DEBUGSoulbindConduitRank; + UpdateField DungeonScore; + UpdateField ActiveCombatTraitConfigID; + UpdateField ItemUpgradeHighOnehandWeaponItemID; + UpdateField ItemUpgradeHighFingerItemID; + UpdateField ItemUpgradeHighFingerWatermark; + UpdateField ItemUpgradeHighTrinketItemID; + UpdateField ItemUpgradeHighTrinketWatermark; + UpdateField LootHistoryInstanceID; + OptionalUpdateField PetStable; + UpdateField RequiredMountCapabilityFlags; + OptionalUpdateField WalkInData; + OptionalUpdateField DelveData; + UpdateFieldArray InvSlots; + UpdateFieldArray RestInfo; + UpdateFieldArray ModDamageDonePos; + UpdateFieldArray ModDamageDoneNeg; + UpdateFieldArray ModDamageDonePercent; + UpdateFieldArray ModHealingDonePercent; + UpdateFieldArray WeaponDmgMultipliers; + UpdateFieldArray WeaponAtkSpeedMultipliers; + UpdateFieldArray BuybackPrice; + UpdateFieldArray BuybackTimestamp; + UpdateFieldArray CombatRatings; + UpdateFieldArray NoReagentCostMask; + UpdateFieldArray ProfessionSkillLine; + UpdateFieldArray BagSlotFlags; + UpdateFieldArray BankBagSlotFlags; + UpdateFieldArray QuestCompleted; + UpdateFieldArray ItemUpgradeHighWatermark; void WriteCreate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Player const* owner, Player const* receiver) const; diff --git a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h index 9422d37bdcb..caa867467e5 100644 --- a/src/server/game/Entities/Object/Updates/ViewerDependentValues.h +++ b/src/server/game/Entities/Object/Updates/ViewerDependentValues.h @@ -345,6 +345,18 @@ public: } }; +template<> +class ViewerDependentValue +{ +public: + using value_type = UF::UnitData::Flags4Tag::value_type; + + static value_type GetValue(UF::UnitData const* unitData, Unit const* /*unit*/, Player const* /*receiver*/) + { + return unitData->Flags4; + } +}; + template<> class ViewerDependentValue { diff --git a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp index 85249caab78..b89d7aab275 100644 --- a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp +++ b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.cpp @@ -56,7 +56,8 @@ void EntityFragmentsHolder::Add(EntityFragment fragment, bool update) if (IsIndirectFragment(UpdateableIds[i])) { ContentsChangedMask |= UpdateableMasks[i]; // set the first bit to true to activate fragment - UpdateableMasks[i] |= 1 << maskIndex++; + ++maskIndex; + UpdateableMasks[i] <<= 1; } } } @@ -96,7 +97,10 @@ void EntityFragmentsHolder::Remove(EntityFragment fragment) { UpdateableMasks[i] = 1 << maskIndex++; if (IsIndirectFragment(UpdateableIds[i])) - UpdateableMasks[i] |= 1 << maskIndex++; + { + ++maskIndex; + UpdateableMasks[i] <<= 1; + } } } } diff --git a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h index dba9e0a11a9..a65ca60978a 100644 --- a/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h +++ b/src/server/game/Entities/Object/Updates/WowCSEntityDefinitions.h @@ -51,7 +51,7 @@ enum class EntityFragment : uint8 FEntityLocalMatrix = 113, FEntityWorldMatrix = 114, CActor = 115, // INDIRECT, - FVendor_C = 117, // UPDATEABLE, + FVendor_C = 117, // UPDATEABLE, INDIRECT, FMirroredObject_C = 119, End = 255, }; @@ -63,7 +63,7 @@ inline constexpr bool IsUpdateableFragment(EntityFragment frag) inline constexpr bool IsIndirectFragment(EntityFragment frag) { - return frag == EntityFragment::CGObject || frag == EntityFragment::CActor; + return frag == EntityFragment::CGObject || frag == EntityFragment::CActor || frag == EntityFragment::FVendor_C; } // common case optimization, make use of the fact that fragment arrays are sorted -- cgit v1.2.3