diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-08-13 00:31:39 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-08-13 00:31:39 +0200 |
| commit | 5cf0c6c8bb2c4e58a2d66ba5f304af34d18a4782 (patch) | |
| tree | 0616f3e83f511aae0e10916f0c22161017e09c24 /src/server/game/Entities/Object | |
| parent | 82f19c898815e3bc5bb6288b0191ee897594f9b5 (diff) | |
Core: Updated to 11.2.0
Diffstat (limited to 'src/server/game/Entities/Object')
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 167 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 1 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateField.h | 116 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.cpp | 1481 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 568 |
5 files changed, 1723 insertions, 610 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index eaea679d01a..d5b732a145e 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -16,8 +16,6 @@ */ #include "Object.h" -#include "AreaTriggerPackets.h" -#include "AreaTriggerTemplate.h" #include "BattlefieldMgr.h" #include "CellImpl.h" #include "CinematicMgr.h" @@ -46,7 +44,6 @@ #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "SpellPackets.h" -#include "StringConvert.h" #include "TemporarySummon.h" #include "Totem.h" #include "Transport.h" @@ -310,6 +307,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe data->WriteBit(flags.NoBirthAnim); data->WriteBit(flags.EnablePortals); data->WriteBit(flags.PlayHoverAnim); + data->WriteBit(flags.ThisIsYou); data->WriteBit(flags.MovementUpdate); data->WriteBit(flags.MovementTransport); data->WriteBit(flags.Stationary); @@ -318,10 +316,8 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe data->WriteBit(flags.Vehicle); data->WriteBit(flags.AnimKit); data->WriteBit(flags.Rotation); - data->WriteBit(flags.AreaTrigger); data->WriteBit(flags.GameObject); data->WriteBit(flags.SmoothPhasing); - data->WriteBit(flags.ThisIsYou); data->WriteBit(flags.SceneObject); data->WriteBit(flags.ActivePlayer); data->WriteBit(flags.Conversation); @@ -329,7 +325,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe if (flags.MovementUpdate) { - Unit const* unit = ToUnit(); + Unit const* unit = static_cast<Unit const*>(this); bool HasFallDirection = unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING); bool HasFall = HasFallDirection || unit->m_movementInfo.jump.fallTime != 0; bool HasSpline = unit->IsSplineEnabled(); @@ -470,14 +466,17 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe } if (flags.CombatVictim) - *data << ToUnit()->GetVictim()->GetGUID(); // CombatVictim + { + Unit const* unit = static_cast<Unit const*>(this); + *data << unit->GetVictim()->GetGUID(); // CombatVictim + } if (flags.ServerTime) *data << uint32(GameTime::GetGameTimeMS()); if (flags.Vehicle) { - Unit const* unit = ToUnit(); + Unit const* unit = static_cast<Unit const*>(this); *data << uint32(unit->GetVehicleKit()->GetVehicleInfo()->ID); // RecID *data << float(unit->GetOrientation()); // InitialRawFacing } @@ -491,7 +490,10 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe } if (flags.Rotation) - *data << uint64(ToGameObject()->GetPackedLocalRotation()); // Rotation + { + GameObject const* gameObject = static_cast<GameObject const*>(this); + *data << uint64(gameObject->GetPackedLocalRotation()); // Rotation + } if (PauseTimes && !PauseTimes->empty()) data->append(PauseTimes->data(), PauseTimes->size()); @@ -502,144 +504,9 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe *data << self->m_movementInfo.transport; } - if (flags.AreaTrigger) - { - AreaTrigger const* areaTrigger = static_cast<AreaTrigger const*>(this); - AreaTriggerCreateProperties const* createProperties = areaTrigger->GetCreateProperties(); - AreaTriggerShapeInfo const& shape = areaTrigger->GetShape(); - - *data << uint32(areaTrigger->GetTimeSinceCreated()); - - *data << areaTrigger->GetRollPitchYaw().PositionXYZStream(); - - switch (shape.Type) - { - case AreaTriggerShapeType::Sphere: - *data << int8(0); - *data << float(shape.SphereDatas.Radius); - *data << float(shape.SphereDatas.RadiusTarget); - break; - case AreaTriggerShapeType::Box: - *data << int8(1); - *data << float(shape.BoxDatas.Extents[0]); - *data << float(shape.BoxDatas.Extents[1]); - *data << float(shape.BoxDatas.Extents[2]); - *data << float(shape.BoxDatas.ExtentsTarget[0]); - *data << float(shape.BoxDatas.ExtentsTarget[1]); - *data << float(shape.BoxDatas.ExtentsTarget[2]); - break; - case AreaTriggerShapeType::Polygon: - *data << int8(3); - *data << int32(shape.PolygonVertices.size()); - *data << int32(shape.PolygonVerticesTarget.size()); - *data << float(shape.PolygonDatas.Height); - *data << float(shape.PolygonDatas.HeightTarget); - - for (TaggedPosition<Position::XY> const& vertice : shape.PolygonVertices) - *data << vertice; - - for (TaggedPosition<Position::XY> const& vertice : shape.PolygonVerticesTarget) - *data << vertice; - break; - case AreaTriggerShapeType::Cylinder: - *data << int8(4); - *data << float(shape.CylinderDatas.Radius); - *data << float(shape.CylinderDatas.RadiusTarget); - *data << float(shape.CylinderDatas.Height); - *data << float(shape.CylinderDatas.HeightTarget); - *data << float(shape.CylinderDatas.LocationZOffset); - *data << float(shape.CylinderDatas.LocationZOffsetTarget); - break; - case AreaTriggerShapeType::Disk: - *data << int8(7); - *data << float(shape.DiskDatas.InnerRadius); - *data << float(shape.DiskDatas.InnerRadiusTarget); - *data << float(shape.DiskDatas.OuterRadius); - *data << float(shape.DiskDatas.OuterRadiusTarget); - *data << float(shape.DiskDatas.Height); - *data << float(shape.DiskDatas.HeightTarget); - *data << float(shape.DiskDatas.LocationZOffset); - *data << float(shape.DiskDatas.LocationZOffsetTarget); - break; - case AreaTriggerShapeType::BoundedPlane: - *data << int8(8); - *data << float(shape.BoundedPlaneDatas.Extents[0]); - *data << float(shape.BoundedPlaneDatas.Extents[1]); - *data << float(shape.BoundedPlaneDatas.ExtentsTarget[0]); - *data << float(shape.BoundedPlaneDatas.ExtentsTarget[1]); - break; - default: - break; - } - - bool hasAbsoluteOrientation = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAbsoluteOrientation); - bool hasDynamicShape = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasDynamicShape); - bool hasAttached = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasAttached); - bool hasFaceMovementDir = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasFaceMovementDir); - bool hasFollowsTerrain = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasFollowsTerrain); - bool hasAlwaysExterior = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::AlwaysExterior); - bool hasUnknown1025 = false; - bool hasTargetRollPitchYaw = createProperties && createProperties->Flags.HasFlag(AreaTriggerCreatePropertiesFlag::HasTargetRollPitchYaw); - bool hasScaleCurveID = createProperties && createProperties->ScaleCurveId != 0; - bool hasMorphCurveID = createProperties && createProperties->MorphCurveId != 0; - bool hasFacingCurveID = createProperties && createProperties->FacingCurveId != 0; - bool hasMoveCurveID = createProperties && createProperties->MoveCurveId != 0; - bool hasMovementScript = false; - bool hasPositionalSoundKitID= false; - - data->WriteBit(hasAbsoluteOrientation); - data->WriteBit(hasDynamicShape); - data->WriteBit(hasAttached); - data->WriteBit(hasFaceMovementDir); - data->WriteBit(hasFollowsTerrain); - data->WriteBit(hasAlwaysExterior); - data->WriteBit(hasUnknown1025); - data->WriteBit(hasTargetRollPitchYaw); - data->WriteBit(hasScaleCurveID); - data->WriteBit(hasMorphCurveID); - data->WriteBit(hasFacingCurveID); - data->WriteBit(hasMoveCurveID); - data->WriteBit(hasPositionalSoundKitID); - data->WriteBit(areaTrigger->HasSplines()); - data->WriteBit(areaTrigger->HasOrbit()); - data->WriteBit(hasMovementScript); - - data->FlushBits(); - - if (areaTrigger->HasSplines()) - WorldPackets::AreaTrigger::WriteAreaTriggerSpline(*data, areaTrigger->GetTimeToTarget(), areaTrigger->GetElapsedTimeForMovement(), areaTrigger->GetSpline()); - - if (hasTargetRollPitchYaw) - *data << areaTrigger->GetTargetRollPitchYaw().PositionXYZStream(); - - if (hasScaleCurveID) - *data << uint32(createProperties->ScaleCurveId); - - if (hasMorphCurveID) - *data << uint32(createProperties->MorphCurveId); - - if (hasFacingCurveID) - *data << uint32(createProperties->FacingCurveId); - - if (hasMoveCurveID) - *data << uint32(createProperties->MoveCurveId); - - if (hasPositionalSoundKitID) - *data << uint32(0); - - //if (hasMovementScript) - // *data << *areaTrigger->GetMovementScript(); // AreaTriggerMovementScriptInfo - - if (areaTrigger->HasOrbit()) - { - using WorldPackets::AreaTrigger::operator<<; - *data << areaTrigger->GetOrbit(); - } - } - if (flags.GameObject) { - GameObject const* gameObject = ToGameObject(); + GameObject const* gameObject = static_cast<GameObject const*>(this); Transport const* transport = gameObject->ToTransport(); bool bit8 = false; @@ -794,10 +661,10 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe if (flags.ActivePlayer) { - Player const* player = ToPlayer(); + Player const* player = static_cast<Player const*>(this); bool HasSceneInstanceIDs = !player->GetSceneMgr().GetSceneTemplateByInstanceMap().empty(); - bool HasRuneState = ToUnit()->GetPowerIndex(POWER_RUNES) != MAX_POWERS; + bool HasRuneState = player->GetPowerIndex(POWER_RUNES) != MAX_POWERS; data->WriteBit(HasSceneInstanceIDs); data->WriteBit(HasRuneState); @@ -805,8 +672,8 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe if (HasSceneInstanceIDs) { *data << uint32(player->GetSceneMgr().GetSceneTemplateByInstanceMap().size()); - for (auto const& itr : player->GetSceneMgr().GetSceneTemplateByInstanceMap()) - *data << uint32(itr.first); + for (auto const& [sceneInstanceId, _] : player->GetSceneMgr().GetSceneTemplateByInstanceMap()) + *data << uint32(sceneInstanceId); } if (HasRuneState) { @@ -823,7 +690,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe if (flags.Conversation) { - Conversation const* self = ToConversation(); + Conversation const* self = static_cast<Conversation const*>(this); if (data->WriteBit(self->GetTextureKitId() != 0)) *data << uint32(self->GetTextureKitId()); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index b5940dc0b73..971b74494e0 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -93,7 +93,6 @@ struct CreateObjectBits bool Vehicle : 1; bool AnimKit : 1; bool Rotation : 1; - bool AreaTrigger : 1; bool GameObject : 1; bool SmoothPhasing : 1; bool ThisIsYou : 1; diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h index ef802f8447d..874b38d87d8 100644 --- a/src/server/game/Entities/Object/Updates/UpdateField.h +++ b/src/server/game/Entities/Object/Updates/UpdateField.h @@ -23,6 +23,7 @@ #include "UpdateMask.h" #include <algorithm> #include <memory> +#include <variant> #include <vector> class ByteBuffer; @@ -68,6 +69,15 @@ namespace UF template<typename T, int32 BlockBit, uint32 Bit> class OptionalUpdateField; + template<typename T> + inline constexpr std::type_identity<T> VariantCase; + + template<typename... Types> + class VariantUpdateFieldBase; + + template<int32 BlockBit, uint32 Bit, typename... Types> + class VariantUpdateField; + template<typename T, bool PublicSet> struct MutableFieldReferenceWithChangesMask; @@ -352,6 +362,24 @@ namespace UF return { *((_value.*field)._value) }; } + template<typename V, int32 BlockBit, uint32 Bit, typename... Types> + std::conditional_t<std::is_base_of_v<IsUpdateFieldStructureTag, V>, + MutableFieldReference<V, PublicSet>, + std::conditional_t<std::is_base_of_v<IsUpdateFieldHolderTag, V>, + MutableNestedFieldReference<V, PublicSet>, + UpdateFieldSetter<V, PublicSet>>> + ModifyValue(VariantUpdateField<BlockBit, Bit, Types...>(T::* field), [[maybe_unused]] std::type_identity<V> type) + { + if (!(_value.*field).template Is<V>()) + (_value.*field).template ConstructValue<V>(); + + if constexpr (BlockBit >= 0) + _value._changesMask.Set(BlockBit); + + _value._changesMask.Set(Bit); + return { *((_value.*field).template Get<V>()) }; + } + private: T& _value; }; @@ -538,6 +566,17 @@ namespace UF _changesMask.Set(Bit); } + template<typename Derived, int32 BlockBit, uint32 Bit, typename... Types> + void MarkChanged(VariantUpdateField<BlockBit, Bit, Types...>(Derived::*)) + { + static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask"); + + if constexpr (BlockBit >= 0) + _changesMask.Set(BlockBit); + + _changesMask.Set(Bit); + } + template<typename Derived, typename T, int32 BlockBit, uint32 Bit> void ClearChanged(UpdateField<T, BlockBit, Bit>(Derived::*)) { @@ -578,6 +617,14 @@ namespace UF _changesMask.Reset(Bit); } + template<typename Derived, int32 BlockBit, uint32 Bit, typename... Types> + void ClearChanged(VariantUpdateField<BlockBit, Bit, Types...>(Derived::*)) + { + static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask"); + + _changesMask.Reset(Bit); + } + Mask const& GetChangesMask() const { return _changesMask; } protected: @@ -614,6 +661,17 @@ namespace UF field._value->ClearChangesMask(); } + template<int32 BlockBit, uint32 Bit, typename... Types> + static void ClearChangesMask(VariantUpdateField<BlockBit, Bit, Types...>& field) + { + if constexpr ((std::is_base_of_v<HasChangesMaskTag, Types> || ...)) + std::visit([]<typename T>(T& value) + { + if constexpr (std::is_base_of_v<HasChangesMaskTag, T>) + value.ClearChangesMask(); + }, field._value); + } + Mask _changesMask; }; @@ -894,6 +952,64 @@ namespace UF { }; + template<typename... Types> + class VariantUpdateFieldBase : public IsUpdateFieldHolderTag + { + template<typename F, bool PublicSet> + friend struct MutableFieldReferenceWithChangesMask; + + template<typename F, bool PublicSet> + friend struct MutableFieldReferenceNoChangesMask; + + template<typename F, bool PublicSet> + friend struct MutableNestedFieldReference; + + template<std::size_t Bits> + friend class HasChangesMask; + + friend class UpdateFieldHolder; + + public: + template<typename T> + bool Is() const { return std::holds_alternative<T>(_value); } + + template<typename T> + T const* Get() const noexcept + { + if (std::holds_alternative<T>(_value)) + return &std::get<T>(_value); + return nullptr; + } + + template<typename Visitor> + decltype(auto) Visit(Visitor&& visitor) const noexcept + { + return std::visit(std::forward<Visitor>(visitor), _value); + } + + private: + template<typename T> + void ConstructValue() + { + _value.template emplace<T>(); + } + + template<typename T> + T* Get() noexcept + { + if (std::holds_alternative<T>(_value)) + return &std::get<T>(_value); + return nullptr; + } + + std::variant<std::monostate, Types...> _value; + }; + + template<int32 BlockBit, uint32 Bit, typename... Types> + class VariantUpdateField : public VariantUpdateFieldBase<Types...> + { + }; + template<typename T> struct ViewerDependentValueTag { diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index a86aa7f9988..f70dc26de37 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -20,6 +20,7 @@ #include "ByteBuffer.h" #include "Corpse.h" #include "DynamicObject.h" +#include "PacketOperators.h" #include "Player.h" #include "ViewerDependentValues.h" @@ -852,18 +853,24 @@ void UnitChannel::WriteCreate(ByteBuffer& data, Unit const* owner, Player const* { data << int32(SpellID); SpellVisual.WriteCreate(data, owner, receiver); + data << uint32(StartTimeMs); + data << uint32(Duration); } void UnitChannel::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const { data << int32(SpellID); SpellVisual.WriteUpdate(data, ignoreChangesMask, owner, receiver); + data << uint32(StartTimeMs); + data << uint32(Duration); } bool UnitChannel::operator==(UnitChannel const& right) const { return SpellID == right.SpellID - && SpellVisual == right.SpellVisual; + && SpellVisual == right.SpellVisual + && StartTimeMs == right.StartTimeMs + && Duration == right.Duration; } void VisibleItem::WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const @@ -937,6 +944,51 @@ bool PassiveSpellHistory::operator==(PassiveSpellHistory const& right) const && AuraSpellID == right.AuraSpellID; } +void UnitAssistActionData::WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const +{ + data << uint8(Type); + data << uint32(VirtualRealmAddress); + data.WriteBits(PlayerName->size(), 6); + data.FlushBits(); + data << WorldPackets::SizedString::Data(*PlayerName); +} + +void UnitAssistActionData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit 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 << uint8(Type); + } + if (changesMask[3]) + { + data << uint32(VirtualRealmAddress); + } + if (changesMask[2]) + { + data.WriteBits(PlayerName->size(), 6); + data.FlushBits(); + data << WorldPackets::SizedString::Data(*PlayerName); + } + } +} + +void UnitAssistActionData::ClearChangesMask() +{ + Base::ClearChangesMask(Type); + Base::ClearChangesMask(PlayerName); + Base::ClearChangesMask(VirtualRealmAddress); + _changesMask.ResetAll(); +} + void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const { ViewerDependentValue<StateWorldEffectIDsTag>::value_type stateWorldEffectIDs = {}; @@ -1148,18 +1200,24 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi { data << ChannelObjects[i]; } + data.FlushBits(); data.WriteBit(Field_314); + data.WriteBits(AssistActionData.has_value(), 1); + if (AssistActionData.has_value()) + { + AssistActionData->WriteCreate(data, owner, receiver); + } data.FlushBits(); } static constexpr void UnitDataAppendAllowedFieldsMaskForFlag(UnitData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) - allowedMaskForTarget |= std::array<uint32, 7>{ 0x00010000u, 0xF0040000u, 0xFF080000u, 0x000007FEu, 0xF0000080u, 0xFF80FFFFu, 0x3FFFFFFFu }; + allowedMaskForTarget |= std::array<uint32, 7>{ 0x00010000u, 0xF0040000u, 0xFF080000u, 0x000007FEu, 0xE0000100u, 0xFF01FFFFu, 0x7FFFFFFFu }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) - allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xF0000080u, 0x0000FFFFu, 0x00000000u }; + allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xE0000100u, 0x0001FFFFu, 0x00000000u }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) - allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0xF0000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0000FF00u }; + allowedMaskForTarget |= std::array<uint32, 7>{ 0x00000000u, 0xF0000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0001FE00u }; } void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) @@ -1169,14 +1227,14 @@ void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFl void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x1FFFFFFFu, 0x00FE0000u, 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, 0x0FFFFFFFu, 0x007F0000u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFEFFFFu, 0x0FFBFFFFu, 0x00F7FFFFu, 0xFFFFF801u, 0x1FFFFFFFu, 0x00FE0000u, 0x00000000u }); UnitDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -1776,84 +1834,93 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor { data << *NameplateAttachToGUID; } + data.WriteBits(AssistActionData.has_value(), 1); + data.FlushBits(); + if (changesMask[135]) + { + if (AssistActionData.has_value()) + { + AssistActionData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } } - if (changesMask[135]) + if (changesMask[136]) { for (uint32 i = 0; i < 10; ++i) { - if (changesMask[136 + i]) + if (changesMask[137 + i]) { data << int32(Power[i]); } - if (changesMask[146 + i]) + if (changesMask[147 + i]) { data << int32(MaxPower[i]); } - if (changesMask[156 + i]) + if (changesMask[157 + i]) { data << float(PowerRegenFlatModifier[i]); } - if (changesMask[166 + i]) + if (changesMask[167 + i]) { data << float(PowerRegenInterruptedFlatModifier[i]); } } } - if (changesMask[176]) + if (changesMask[177]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[177 + i]) + if (changesMask[178 + i]) { VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[180]) + if (changesMask[181]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[181 + i]) + if (changesMask[182 + i]) { data << uint32(AttackRoundBaseTime[i]); } } } - if (changesMask[183]) + if (changesMask[184]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[184 + i]) + if (changesMask[185 + i]) { data << int32(Stats[i]); } - if (changesMask[188 + i]) + if (changesMask[189 + i]) { data << int32(StatPosBuff[i]); } - if (changesMask[192 + i]) + if (changesMask[193 + i]) { data << int32(StatNegBuff[i]); } - if (changesMask[196 + i]) + if (changesMask[197 + i]) { data << int32(StatSupportBuff[i]); } } } - if (changesMask[200]) + if (changesMask[201]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[201 + i]) + if (changesMask[202 + i]) { data << int32(Resistances[i]); } - if (changesMask[208 + i]) + if (changesMask[209 + i]) { data << int32(BonusResistanceMods[i]); } - if (changesMask[215 + i]) + if (changesMask[216 + i]) { data << int32(ManaCostModifier[i]); } @@ -1994,6 +2061,7 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(Field_31C); Base::ClearChangesMask(Field_320); Base::ClearChangesMask(NameplateAttachToGUID); + Base::ClearChangesMask(AssistActionData); Base::ClearChangesMask(Power); Base::ClearChangesMask(MaxPower); Base::ClearChangesMask(PowerRegenFlatModifier); @@ -2196,7 +2264,7 @@ void PetCreatureName::WriteCreate(ByteBuffer& data, Player const* owner, Player { data << uint32(CreatureID); data.WriteBits(Name->size(), 8); - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); data.FlushBits(); } @@ -2218,7 +2286,7 @@ void PetCreatureName::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Play if (changesMask[2]) { data.WriteBits(Name->size(), 8); - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); } } data.FlushBits(); @@ -2252,6 +2320,50 @@ bool CTROptions::operator==(CTROptions const& right) const && ChromieTimeExpansionMask == right.ChromieTimeExpansionMask; } +void LeaverInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << BnetAccountGUID; + data << float(LeaveScore); + data << uint32(SeasonID); + data << uint32(TotalLeaves); + data << uint32(TotalSuccesses); + data << int32(ConsecutiveSuccesses); + data << int64(LastPenaltyTime); + data << int64(LeaverExpirationTime); + data << int32(Unknown_1120); + data.WriteBits(LeaverStatus, 1); + data.FlushBits(); +} + +void LeaverInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + data << BnetAccountGUID; + data << float(LeaveScore); + data << uint32(SeasonID); + data << uint32(TotalLeaves); + data << uint32(TotalSuccesses); + data << int32(ConsecutiveSuccesses); + data << int64(LastPenaltyTime); + data << int64(LeaverExpirationTime); + data << int32(Unknown_1120); + data.WriteBits(LeaverStatus, 1); + data.FlushBits(); +} + +bool LeaverInfo::operator==(LeaverInfo const& right) const +{ + return BnetAccountGUID == right.BnetAccountGUID + && LeaveScore == right.LeaveScore + && SeasonID == right.SeasonID + && TotalLeaves == right.TotalLeaves + && TotalSuccesses == right.TotalSuccesses + && ConsecutiveSuccesses == right.ConsecutiveSuccesses + && LastPenaltyTime == right.LastPenaltyTime + && LeaverExpirationTime == right.LeaverExpirationTime + && Unknown_1120 == right.Unknown_1120 + && LeaverStatus == right.LeaverStatus; +} + void DeclinedNames::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { for (uint32 i = 0; i < 5; ++i) @@ -2260,7 +2372,7 @@ void DeclinedNames::WriteCreate(ByteBuffer& data, Player const* owner, Player co } for (uint32 i = 0; i < 5; ++i) { - data.WriteString(Name[i]); + data << WorldPackets::SizedString::Data(Name[i]); } data.FlushBits(); } @@ -2292,7 +2404,7 @@ void DeclinedNames::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player { if (changesMask[1 + i]) { - data.WriteString(Name[i]); + data << WorldPackets::SizedString::Data(Name[i]); } } } @@ -2398,6 +2510,7 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi data << int32(FakeInebriation); data << uint32(VirtualPlayerRealm); data << uint32(CurrentSpecID); + data << int32(CurrentCombatTraitConfigSubTreeID); data << int32(TaxiMountAnimKitID); for (uint32 i = 0; i < 6; ++i) { @@ -2458,7 +2571,8 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi data.WriteBit(HasLevelLink); data.WriteBits(DeclinedNames.has_value(), 1); data << *DungeonScore; - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); + LeaverInfo->WriteCreate(data, owner, receiver); for (uint32 i = 0; i < 16; ++i) { data << VisibleEquipableSpells[i]; @@ -2477,7 +2591,7 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi static constexpr void PlayerDataAppendAllowedFieldsMaskForFlag(PlayerData::Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - allowedMaskForTarget |= std::array<uint32, 11>{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u }; + allowedMaskForTarget |= std::array<uint32, 11>{ 0x00000022u, 0xFFF80000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000007u, 0x00000000u, 0x00000000u, 0x00000000u }; } void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) @@ -2487,14 +2601,14 @@ void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, Enum void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u }); + Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0007FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFF8u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000000Fu }); PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const { - Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u }); + Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0007FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFF8u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000000Fu }); PlayerDataAppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -2708,74 +2822,82 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign } if (changesMask[29]) { - data << int32(TaxiMountAnimKitID); + data << int32(CurrentCombatTraitConfigSubTreeID); } if (changesMask[30]) { - data << uint8(CurrentBattlePetBreedQuality); + data << int32(TaxiMountAnimKitID); } if (changesMask[31]) { - data << int32(HonorLevel); + data << uint8(CurrentBattlePetBreedQuality); } } if (changesMask[32]) { if (changesMask[33]) { + data << int32(HonorLevel); + } + if (changesMask[34]) + { data << int64(LogoutTime); } - if (changesMask[35]) + if (changesMask[36]) { data << int32(Field_1AC); } - if (changesMask[36]) + if (changesMask[37]) { data << int32(Field_1B0); } - if (changesMask[37]) + if (changesMask[38]) { data << int32(CurrentBattlePetSpeciesID); } - if (changesMask[38]) + if (changesMask[39]) { CtrOptions->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[39]) + if (changesMask[40]) { data << int32(CovenantID); } - if (changesMask[40]) + if (changesMask[41]) { data << int32(SoulbindID); } - if (changesMask[42]) + if (changesMask[44]) { data << *SpectateTarget; } - if (changesMask[43]) + if (changesMask[45]) { data << int32(Field_200); } - if (changesMask[45]) + if (changesMask[47]) { PersonalTabard->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[34]) + if (changesMask[35]) { data.WriteBits(Name->size(), 6); } data.WriteBits(DeclinedNames.has_value(), 1); data.FlushBits(); - if (changesMask[41]) + if (changesMask[42]) { data << *DungeonScore; } - if (changesMask[34]) + if (changesMask[35]) { - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); } - if (changesMask[44]) + if (changesMask[43]) + { + LeaverInfo->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[46]) { if (DeclinedNames.has_value()) { @@ -2783,21 +2905,21 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign } } } - if (changesMask[46]) + if (changesMask[48]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[47 + i]) + if (changesMask[49 + i]) { data << uint8(PartyType[i]); } } } - if (changesMask[49]) + if (changesMask[51]) { for (uint32 i = 0; i < 175; ++i) { - if (changesMask[50 + i]) + if (changesMask[52 + i]) { if (noQuestLogChangesMask) QuestLog[i].WriteCreate(data, owner, receiver); @@ -2806,51 +2928,51 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign } } } - if (changesMask[225]) + if (changesMask[227]) { for (uint32 i = 0; i < 19; ++i) { - if (changesMask[226 + i]) + if (changesMask[228 + i]) { VisibleItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[245]) + if (changesMask[247]) { for (uint32 i = 0; i < 6; ++i) { - if (changesMask[246 + i]) + if (changesMask[248 + i]) { data << float(AvgItemLevel[i]); } } } - if (changesMask[252]) + if (changesMask[254]) { for (uint32 i = 0; i < 32; ++i) { - if (changesMask[253 + i]) + if (changesMask[255 + i]) { ForcedReactions[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[302]) + if (changesMask[304]) { for (uint32 i = 0; i < 19; ++i) { - if (changesMask[303 + i]) + if (changesMask[305 + i]) { data << uint32(Field_3120[i]); } } } - if (changesMask[285]) + if (changesMask[287]) { for (uint32 i = 0; i < 16; ++i) { - if (changesMask[286 + i]) + if (changesMask[288 + i]) { data << VisibleEquipableSpells[i]; } @@ -2889,6 +3011,7 @@ void PlayerData::ClearChangesMask() Base::ClearChangesMask(FakeInebriation); Base::ClearChangesMask(VirtualPlayerRealm); Base::ClearChangesMask(CurrentSpecID); + Base::ClearChangesMask(CurrentCombatTraitConfigSubTreeID); Base::ClearChangesMask(TaxiMountAnimKitID); Base::ClearChangesMask(CurrentBattlePetBreedQuality); Base::ClearChangesMask(HonorLevel); @@ -2901,6 +3024,7 @@ void PlayerData::ClearChangesMask() Base::ClearChangesMask(CovenantID); Base::ClearChangesMask(SoulbindID); Base::ClearChangesMask(DungeonScore); + Base::ClearChangesMask(LeaverInfo); Base::ClearChangesMask(SpectateTarget); Base::ClearChangesMask(Field_200); Base::ClearChangesMask(DeclinedNames); @@ -3613,6 +3737,7 @@ void TraitEntry::WriteCreate(ByteBuffer& data, Player const* owner, Player const data << int32(TraitNodeEntryID); data << int32(Rank); data << int32(GrantedRanks); + data << int32(BonusRanks); } void TraitEntry::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const @@ -3621,6 +3746,7 @@ void TraitEntry::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player co data << int32(TraitNodeEntryID); data << int32(Rank); data << int32(GrantedRanks); + data << int32(BonusRanks); } bool TraitEntry::operator==(TraitEntry const& right) const @@ -3628,7 +3754,8 @@ bool TraitEntry::operator==(TraitEntry const& right) const return TraitNodeID == right.TraitNodeID && TraitNodeEntryID == right.TraitNodeEntryID && Rank == right.Rank - && GrantedRanks == right.GrantedRanks; + && GrantedRanks == right.GrantedRanks + && BonusRanks == right.BonusRanks; } void TraitSubTreeCache::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const @@ -3692,7 +3819,7 @@ void TraitConfig::WriteCreate(ByteBuffer& data, Player const* owner, Player cons { SubTrees[i].WriteCreate(data, owner, receiver); } - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); data.FlushBits(); } @@ -3802,7 +3929,7 @@ void TraitConfig::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player c if (changesMask[5]) { data.WriteBits(Name->size(), 9); - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); } } data.FlushBits(); @@ -3987,7 +4114,7 @@ void CraftingOrderData::WriteCreate(ByteBuffer& data, Player const* owner, Playe { Reagents[i].WriteCreate(data, owner, receiver); } - data.WriteString(CustomerNotes); + data << WorldPackets::SizedString::Data(*CustomerNotes); if (Customer.has_value()) { Customer->WriteCreate(data, owner, receiver); @@ -4123,7 +4250,7 @@ void CraftingOrderData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Pl { if (changesMask[20]) { - data.WriteString(CustomerNotes); + data << WorldPackets::SizedString::Data(*CustomerNotes); } if (changesMask[21]) { @@ -4398,7 +4525,7 @@ void StablePetInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player co data << uint8(PetFlags); data << uint32(Specialization); data.WriteBits(Name->size(), 8); - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); data.FlushBits(); } @@ -4444,7 +4571,7 @@ void StablePetInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player if (changesMask[6]) { data.WriteBits(Name->size(), 8); - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); } } data.FlushBits(); @@ -4565,9 +4692,9 @@ void BankTabSettings::WriteCreate(ByteBuffer& data, Player const* owner, Player data.WriteBits(Icon->size(), 9); data.WriteBits(Description->size(), 14); data << int32(DepositFlags); - data.WriteString(Name); - data.WriteString(Icon); - data.WriteString(Description); + data << WorldPackets::SizedString::Data(*Name); + data << WorldPackets::SizedString::Data(*Icon); + data << WorldPackets::SizedString::Data(*Description); data.FlushBits(); } @@ -4598,15 +4725,15 @@ void BankTabSettings::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Play } if (changesMask[0]) { - data.WriteString(Name); + data << WorldPackets::SizedString::Data(*Name); } if (changesMask[1]) { - data.WriteString(Icon); + data << WorldPackets::SizedString::Data(*Icon); } if (changesMask[2]) { - data.WriteString(Description); + data << WorldPackets::SizedString::Data(*Description); } data.FlushBits(); } @@ -4687,6 +4814,47 @@ bool DelveData::operator==(DelveData const& right) const && Started == right.Started; } +void ChallengeModeData::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << int32(Unknown_1120_1); + data << int32(Unknown_1120_2); + data << uint64(Unknown_1120_3); + data << int64(Unknown_1120_4); + data << KeystoneOwnerGUID; + data << LeaverGUID; + data.WriteBits(IsActive, 1); + data.WriteBits(HasRestrictions, 1); + data.WriteBits(CanVoteAbandon, 1); + data.FlushBits(); +} + +void ChallengeModeData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + data << int32(Unknown_1120_1); + data << int32(Unknown_1120_2); + data << uint64(Unknown_1120_3); + data << int64(Unknown_1120_4); + data << KeystoneOwnerGUID; + data << LeaverGUID; + data.WriteBits(IsActive, 1); + data.WriteBits(HasRestrictions, 1); + data.WriteBits(CanVoteAbandon, 1); + data.FlushBits(); +} + +bool ChallengeModeData::operator==(ChallengeModeData const& right) const +{ + return Unknown_1120_1 == right.Unknown_1120_1 + && Unknown_1120_2 == right.Unknown_1120_2 + && Unknown_1120_3 == right.Unknown_1120_3 + && Unknown_1120_4 == right.Unknown_1120_4 + && KeystoneOwnerGUID == right.KeystoneOwnerGUID + && LeaverGUID == right.LeaverGUID + && IsActive == right.IsActive + && HasRestrictions == right.HasRestrictions + && CanVoteAbandon == right.CanVoteAbandon; +} + void Research::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { data << int16(ResearchProjectID); @@ -4704,7 +4872,7 @@ bool Research::operator==(Research const& right) const void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const { - for (uint32 i = 0; i < 232; ++i) + for (uint32 i = 0; i < 105; ++i) { data << InvSlots[i]; } @@ -4819,14 +4987,11 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { data << uint32(BagSlotFlags[i]); } - for (uint32 i = 0; i < 7; ++i) - { - data << uint32(BankBagSlotFlags[i]); - } data << int32(Honor); data << int32(HonorNextLevel); data << int32(PerksProgramCurrency); data << uint8(NumBankSlots); + data << uint8(NumCharacterBankTabs); data << uint8(NumAccountBankTabs); for (uint32 i = 0; i < 1; ++i) { @@ -5017,9 +5182,11 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f data.WriteBit(HasPerksProgramPendingReward); data.WriteBits(QuestSession.has_value(), 1); data.WriteBits(PetStable.has_value(), 1); + data.WriteBits(CharacterBankTabSettings.size(), 3); data.WriteBits(AccountBankTabSettings.size(), 3); data.WriteBits(WalkInData.has_value(), 1); data.WriteBits(DelveData.has_value(), 1); + data.WriteBits(ChallengeModeData.has_value(), 1); data.FlushBits(); ResearchHistory->WriteCreate(data, owner, receiver); if (QuestSession.has_value()) @@ -5049,6 +5216,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { PetStable->WriteCreate(data, owner, receiver); } + for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) + { + CharacterBankTabSettings[i].WriteCreate(data, owner, receiver); + } for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) { AccountBankTabSettings[i].WriteCreate(data, owner, receiver); @@ -5061,6 +5232,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { DelveData->WriteCreate(data, owner, receiver); } + if (ChallengeModeData.has_value()) + { + ChallengeModeData->WriteCreate(data, owner, receiver); + } data.FlushBits(); } @@ -5071,8 +5246,8 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const { - data.WriteBits(changesMask.GetBlocksMask(0), 17); - for (uint32 i = 0; i < 17; ++i) + data.WriteBits(changesMask.GetBlocksMask(0), 13); + for (uint32 i = 0; i < 13; ++i) if (changesMask.GetBlock(i)) data.WriteBits(changesMask.GetBlock(i), 32); @@ -5131,11 +5306,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data); } } - if (changesMask[42]) + if (changesMask[43]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[43]) + if (changesMask[44]) { if (!ignoreNestedChangesMask) ResearchSites[i].WriteUpdateMask(data); @@ -5144,11 +5319,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) ResearchSiteProgress[i].WriteUpdateMask(data); @@ -5157,11 +5332,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[46]) + if (changesMask[47]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[47]) + if (changesMask[48]) { if (!ignoreNestedChangesMask) Research[i].WriteUpdateMask(data); @@ -5170,11 +5345,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 < ResearchSites[i].size(); ++j) { @@ -5186,11 +5361,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 < ResearchSiteProgress[i].size(); ++j) { @@ -5202,11 +5377,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[46]) + if (changesMask[47]) { for (uint32 i = 0; i < 1; ++i) { - if (changesMask[47]) + if (changesMask[48]) { for (uint32 j = 0; j < Research[i].size(); ++j) { @@ -5731,6 +5906,13 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo if (changesMask[41]) { if (!ignoreNestedChangesMask) + CharacterBankTabSettings.WriteUpdateMask(data, 3); + else + WriteCompleteDynamicFieldUpdateMask(CharacterBankTabSettings.size(), data, 3); + } + if (changesMask[42]) + { + if (!ignoreNestedChangesMask) AccountBankTabSettings.WriteUpdateMask(data, 3); else WriteCompleteDynamicFieldUpdateMask(AccountBankTabSettings.size(), data, 3); @@ -5784,6 +5966,16 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } if (changesMask[41]) { + for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i) + { + if (CharacterBankTabSettings.HasChanged(i) || ignoreNestedChangesMask) + { + CharacterBankTabSettings[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[42]) + { for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i) { if (AccountBankTabSettings.HasChanged(i) || ignoreNestedChangesMask) @@ -5792,364 +5984,368 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[48]) - { - data << *FarsightObject; - } if (changesMask[49]) { - data << *SummonedBattlePetGUID; + data << *FarsightObject; } if (changesMask[50]) { - data << uint64(Coinage); + data << *SummonedBattlePetGUID; } if (changesMask[51]) { - data << uint64(AccountBankCoinage); + data << uint64(Coinage); } if (changesMask[52]) { - data << int32(XP); + data << uint64(AccountBankCoinage); } if (changesMask[53]) { - data << int32(NextLevelXP); + data << int32(XP); } if (changesMask[54]) { - data << int32(TrialXP); + data << int32(NextLevelXP); } if (changesMask[55]) { - Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << int32(TrialXP); } if (changesMask[56]) { - data << int32(CharacterPoints); + Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[57]) { - data << int32(MaxTalentTiers); + data << int32(CharacterPoints); } if (changesMask[58]) { - data << uint32(TrackCreatureMask); + data << int32(MaxTalentTiers); } if (changesMask[59]) { - data << float(MainhandExpertise); + data << uint32(TrackCreatureMask); } if (changesMask[60]) { - data << float(OffhandExpertise); + data << float(MainhandExpertise); } if (changesMask[61]) { - data << float(RangedExpertise); + data << float(OffhandExpertise); } if (changesMask[62]) { - data << float(CombatRatingExpertise); + data << float(RangedExpertise); } if (changesMask[63]) { - data << float(BlockPercentage); + data << float(CombatRatingExpertise); } if (changesMask[64]) { - data << float(DodgePercentage); + data << float(BlockPercentage); } if (changesMask[65]) { - data << float(DodgePercentageFromAttribute); + data << float(DodgePercentage); } if (changesMask[66]) { - data << float(ParryPercentage); + data << float(DodgePercentageFromAttribute); } if (changesMask[67]) { - data << float(ParryPercentageFromAttribute); + data << float(ParryPercentage); } if (changesMask[68]) { - data << float(CritPercentage); + data << float(ParryPercentageFromAttribute); } if (changesMask[69]) { - data << float(RangedCritPercentage); + data << float(CritPercentage); } } if (changesMask[70]) { if (changesMask[71]) { - data << float(OffhandCritPercentage); + data << float(RangedCritPercentage); } if (changesMask[72]) { - data << float(SpellCritPercentage); + data << float(OffhandCritPercentage); } if (changesMask[73]) { - data << int32(ShieldBlock); + data << float(SpellCritPercentage); } if (changesMask[74]) { - data << float(ShieldBlockCritPercentage); + data << int32(ShieldBlock); } if (changesMask[75]) { - data << float(Mastery); + data << float(ShieldBlockCritPercentage); } if (changesMask[76]) { - data << float(Speed); + data << float(Mastery); } if (changesMask[77]) { - data << float(Avoidance); + data << float(Speed); } if (changesMask[78]) { - data << float(Sturdiness); + data << float(Avoidance); } if (changesMask[79]) { - data << int32(Versatility); + data << float(Sturdiness); } if (changesMask[80]) { - data << float(VersatilityBonus); + data << int32(Versatility); } if (changesMask[81]) { - data << float(PvpPowerDamage); + data << float(VersatilityBonus); } if (changesMask[82]) { - data << float(PvpPowerHealing); + data << float(PvpPowerDamage); } if (changesMask[83]) { - BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << float(PvpPowerHealing); } if (changesMask[84]) { - data << int32(ModHealingDonePos); + BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[85]) { - data << float(ModHealingPercent); + data << int32(ModHealingDonePos); } if (changesMask[86]) { - data << float(ModPeriodicHealingDonePercent); + data << float(ModHealingPercent); } if (changesMask[87]) { - data << float(ModSpellPowerPercent); + data << float(ModPeriodicHealingDonePercent); } if (changesMask[88]) { - data << float(ModResiliencePercent); + data << float(ModSpellPowerPercent); } if (changesMask[89]) { - data << float(OverrideSpellPowerByAPPercent); + data << float(ModResiliencePercent); } if (changesMask[90]) { - data << float(OverrideAPBySpellPowerPercent); + data << float(OverrideSpellPowerByAPPercent); } if (changesMask[91]) { - data << int32(ModTargetResistance); + data << float(OverrideAPBySpellPowerPercent); } if (changesMask[92]) { - data << int32(ModTargetPhysicalResistance); + data << int32(ModTargetResistance); } if (changesMask[93]) { - data << uint32(LocalFlags); + data << int32(ModTargetPhysicalResistance); } if (changesMask[94]) { - data << uint8(GrantableLevels); + data << uint32(LocalFlags); } if (changesMask[95]) { - data << uint8(MultiActionBars); + data << uint8(GrantableLevels); } if (changesMask[96]) { - data << uint8(LifetimeMaxRank); + data << uint8(MultiActionBars); } if (changesMask[97]) { - data << uint8(NumRespecs); + data << uint8(LifetimeMaxRank); } if (changesMask[98]) { - data << uint32(PvpMedals); + data << uint8(NumRespecs); } if (changesMask[99]) { - data << uint16(TodayHonorableKills); + data << uint32(PvpMedals); } if (changesMask[100]) { - data << uint16(YesterdayHonorableKills); + data << uint16(TodayHonorableKills); } if (changesMask[101]) { - data << uint32(LifetimeHonorableKills); + data << uint16(YesterdayHonorableKills); } } if (changesMask[102]) { if (changesMask[103]) { - data << int32(WatchedFactionIndex); + data << uint32(LifetimeHonorableKills); } if (changesMask[104]) { - data << int32(MaxLevel); + data << int32(WatchedFactionIndex); } if (changesMask[105]) { - data << int32(ScalingPlayerLevelDelta); + data << int32(MaxLevel); } if (changesMask[106]) { - data << int32(MaxCreatureScalingLevel); + data << int32(ScalingPlayerLevelDelta); } if (changesMask[107]) { - data << int32(PetSpellPower); + data << int32(MaxCreatureScalingLevel); } if (changesMask[108]) { - data << float(UiHitModifier); + data << int32(PetSpellPower); } if (changesMask[109]) { - data << float(UiSpellHitModifier); + data << float(UiHitModifier); } if (changesMask[110]) { - data << int32(HomeRealmTimeOffset); + data << float(UiSpellHitModifier); } if (changesMask[111]) { - data << float(ModPetHaste); + data << int32(HomeRealmTimeOffset); } if (changesMask[112]) { - data << int8(JailersTowerLevelMax); + data << float(ModPetHaste); } if (changesMask[113]) { - data << int8(JailersTowerLevel); + data << int8(JailersTowerLevelMax); } if (changesMask[114]) { - data << uint8(LocalRegenFlags); + data << int8(JailersTowerLevel); } if (changesMask[115]) { - data << uint8(AuraVision); + data << uint8(LocalRegenFlags); } if (changesMask[116]) { - data << uint8(NumBackpackSlots); + data << uint8(AuraVision); } if (changesMask[117]) { - data << int32(OverrideSpellsID); + data << uint8(NumBackpackSlots); } if (changesMask[118]) { - data << uint16(LootSpecID); + data << int32(OverrideSpellsID); } if (changesMask[119]) { - data << uint32(OverrideZonePVPType); + data << uint16(LootSpecID); } if (changesMask[120]) { - data << int32(Honor); + data << uint32(OverrideZonePVPType); } if (changesMask[121]) { - data << int32(HonorNextLevel); + data << int32(Honor); } if (changesMask[122]) { - data << int32(PerksProgramCurrency); + data << int32(HonorNextLevel); } if (changesMask[123]) { - data << uint8(NumBankSlots); + data << int32(PerksProgramCurrency); } if (changesMask[124]) { - data << uint8(NumAccountBankTabs); + data << uint8(NumBankSlots); } - if (changesMask[129]) + if (changesMask[125]) { - data << int32(UiChromieTimeExpansionID); + data << uint8(NumCharacterBankTabs); } - if (changesMask[130]) + if (changesMask[126]) { - data << int32(TimerunningSeasonID); + data << uint8(NumAccountBankTabs); } if (changesMask[131]) { - data << int32(TransportServerTime); + data << int32(UiChromieTimeExpansionID); } if (changesMask[132]) { - data << uint32(WeeklyRewardsPeriodSinceOrigin); + data << int32(TimerunningSeasonID); } if (changesMask[133]) { - data << int16(DEBUGSoulbindConduitRank); + data << int32(TransportServerTime); } } if (changesMask[134]) { + if (changesMask[135]) + { + data << uint32(WeeklyRewardsPeriodSinceOrigin); + } if (changesMask[136]) { + data << int16(DEBUGSoulbindConduitRank); + } + if (changesMask[138]) + { data << uint32(ActiveCombatTraitConfigID); } - if (changesMask[137]) + if (changesMask[139]) { data << int32(ItemUpgradeHighOnehandWeaponItemID); } - if (changesMask[138]) + if (changesMask[140]) { data << int32(ItemUpgradeHighFingerItemID); } - if (changesMask[139]) + if (changesMask[141]) { data << float(ItemUpgradeHighFingerWatermark); } - if (changesMask[140]) + if (changesMask[142]) { data << int32(ItemUpgradeHighTrinketItemID); } - if (changesMask[141]) + if (changesMask[143]) { data << float(ItemUpgradeHighTrinketWatermark); } - if (changesMask[142]) + if (changesMask[144]) { data << uint64(LootHistoryInstanceID); } - if (changesMask[144]) + if (changesMask[146]) { data << uint8(RequiredMountCapabilityFlags); } @@ -6163,183 +6359,181 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo data.WriteBits(PetStable.has_value(), 1); data.WriteBits(WalkInData.has_value(), 1); data.WriteBits(DelveData.has_value(), 1); + data.WriteBits(ChallengeModeData.has_value(), 1); } data.FlushBits(); if (changesMask[102]) { - if (changesMask[125]) + if (changesMask[127]) { ResearchHistory->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[127]) + if (changesMask[129]) { if (QuestSession.has_value()) { QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[126]) + if (changesMask[128]) { data << *FrozenPerksVendorItem; } - if (changesMask[128]) + if (changesMask[130]) { Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } if (changesMask[134]) { - if (changesMask[135]) + if (changesMask[137]) { data << *DungeonScore; } - if (changesMask[143]) + if (changesMask[145]) { if (PetStable.has_value()) { PetStable->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[145]) + if (changesMask[147]) { if (WalkInData.has_value()) { WalkInData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[146]) + if (changesMask[148]) { if (DelveData.has_value()) { DelveData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } + if (changesMask[149]) + { + if (ChallengeModeData.has_value()) + { + ChallengeModeData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } } - if (changesMask[147]) + if (changesMask[150]) { - for (uint32 i = 0; i < 232; ++i) + for (uint32 i = 0; i < 105; ++i) { - if (changesMask[148 + i]) + if (changesMask[151 + i]) { data << InvSlots[i]; } } } - if (changesMask[380]) + if (changesMask[256]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[381 + i]) + if (changesMask[257 + i]) { RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[383]) + if (changesMask[259]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[384 + i]) + if (changesMask[260 + i]) { data << int32(ModDamageDonePos[i]); } - if (changesMask[391 + i]) + if (changesMask[267 + i]) { data << int32(ModDamageDoneNeg[i]); } - if (changesMask[398 + i]) + if (changesMask[274 + i]) { data << float(ModDamageDonePercent[i]); } - if (changesMask[405 + i]) + if (changesMask[281 + i]) { data << float(ModHealingDonePercent[i]); } } } - if (changesMask[412]) + if (changesMask[288]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[413 + i]) + if (changesMask[289 + i]) { data << float(WeaponDmgMultipliers[i]); } - if (changesMask[416 + i]) + if (changesMask[292 + i]) { data << float(WeaponAtkSpeedMultipliers[i]); } } } - if (changesMask[419]) + if (changesMask[295]) { for (uint32 i = 0; i < 12; ++i) { - if (changesMask[420 + i]) + if (changesMask[296 + i]) { data << uint32(BuybackPrice[i]); } - if (changesMask[432 + i]) + if (changesMask[308 + i]) { data << int64(BuybackTimestamp[i]); } } } - if (changesMask[444]) + if (changesMask[320]) { for (uint32 i = 0; i < 32; ++i) { - if (changesMask[445 + i]) + if (changesMask[321 + i]) { data << int32(CombatRatings[i]); } } } - if (changesMask[477]) + if (changesMask[353]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[478 + i]) + if (changesMask[354 + i]) { data << uint32(NoReagentCostMask[i]); } } } - if (changesMask[482]) + if (changesMask[358]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[483 + i]) + if (changesMask[359 + i]) { data << int32(ProfessionSkillLine[i]); } } } - if (changesMask[485]) + if (changesMask[361]) { for (uint32 i = 0; i < 5; ++i) { - if (changesMask[486 + i]) + if (changesMask[362 + i]) { data << uint32(BagSlotFlags[i]); } } } - if (changesMask[491]) - { - for (uint32 i = 0; i < 7; ++i) - { - if (changesMask[492 + i]) - { - data << uint32(BankBagSlotFlags[i]); - } - } - } - if (changesMask[499]) + if (changesMask[367]) { for (uint32 i = 0; i < 17; ++i) { - if (changesMask[500 + i]) + if (changesMask[368 + i]) { data << float(ItemUpgradeHighWatermark[i]); } @@ -6392,6 +6586,7 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(CharacterRestrictions); Base::ClearChangesMask(TraitConfigs); Base::ClearChangesMask(CraftingOrders); + Base::ClearChangesMask(CharacterBankTabSettings); Base::ClearChangesMask(AccountBankTabSettings); Base::ClearChangesMask(FarsightObject); Base::ClearChangesMask(SummonedBattlePetGUID); @@ -6467,6 +6662,7 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(HonorNextLevel); Base::ClearChangesMask(PerksProgramCurrency); Base::ClearChangesMask(NumBankSlots); + Base::ClearChangesMask(NumCharacterBankTabs); Base::ClearChangesMask(NumAccountBankTabs); Base::ClearChangesMask(ResearchHistory); Base::ClearChangesMask(FrozenPerksVendorItem); @@ -6489,6 +6685,7 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(RequiredMountCapabilityFlags); Base::ClearChangesMask(WalkInData); Base::ClearChangesMask(DelveData); + Base::ClearChangesMask(ChallengeModeData); Base::ClearChangesMask(InvSlots); Base::ClearChangesMask(RestInfo); Base::ClearChangesMask(ModDamageDonePos); @@ -6503,11 +6700,44 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(NoReagentCostMask); Base::ClearChangesMask(ProfessionSkillLine); Base::ClearChangesMask(BagSlotFlags); - Base::ClearChangesMask(BankBagSlotFlags); Base::ClearChangesMask(ItemUpgradeHighWatermark); _changesMask.ResetAll(); } +void GameObjectAssistActionData::WriteCreate(ByteBuffer& data, GameObject const* owner, Player const* receiver) const +{ + data.WriteBits(PlayerName.size(), 6); + data.WriteBits(MonsterName.size() + 1, 11); + data << uint32(VirtualRealmAddress); + data << uint8(Sex); + data << int64(Time); + data << int32(DelveTier); + data << WorldPackets::SizedString::Data(PlayerName); + data << WorldPackets::SizedCString::Data(MonsterName); +} + +void GameObjectAssistActionData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, GameObject const* owner, Player const* receiver) const +{ + data.WriteBits(PlayerName.size(), 6); + data.WriteBits(MonsterName.size() + 1, 11); + data << uint32(VirtualRealmAddress); + data << uint8(Sex); + data << int64(Time); + data << int32(DelveTier); + data << WorldPackets::SizedString::Data(PlayerName); + data << WorldPackets::SizedCString::Data(MonsterName); +} + +bool GameObjectAssistActionData::operator==(GameObjectAssistActionData const& right) const +{ + return PlayerName == right.PlayerName + && MonsterName == right.MonsterName + && VirtualRealmAddress == right.VirtualRealmAddress + && Sex == right.Sex + && Time == right.Time + && DelveTier == right.DelveTier; +} + void GameObjectData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const { ViewerDependentValue<StateWorldEffectIDsTag>::value_type stateWorldEffectIDs = {}; @@ -6552,6 +6782,12 @@ void GameObjectData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fie { data << int32(WorldEffects[i]); } + data.WriteBits(AssistActionData.has_value(), 1); + data.FlushBits(); + if (AssistActionData.has_value()) + { + AssistActionData->WriteCreate(data, owner, receiver); + } } void GameObjectData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const @@ -6561,7 +6797,7 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fie void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) const { - data.WriteBits(changesMask.GetBlock(0), 25); + data.WriteBits(changesMask.GetBlock(0), 26); ViewerDependentValue<StateWorldEffectIDsTag>::value_type stateWorldEffectIDs = {}; @@ -6705,6 +6941,15 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool { data << uint32(UiWidgetItemUnknown1000); } + data.WriteBits(AssistActionData.has_value(), 1); + data.FlushBits(); + if (changesMask[25]) + { + if (AssistActionData.has_value()) + { + AssistActionData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } } } @@ -6734,6 +6979,7 @@ void GameObjectData::ClearChangesMask() Base::ClearChangesMask(UiWidgetItemID); Base::ClearChangesMask(UiWidgetItemQuality); Base::ClearChangesMask(UiWidgetItemUnknown1000); + Base::ClearChangesMask(AssistActionData); _changesMask.ResetAll(); } @@ -7044,6 +7290,514 @@ void VisualAnim::ClearChangesMask() _changesMask.ResetAll(); } +void ForceSetAreaTriggerPositionAndRotation::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << TriggerGUID; + data << Position; + data << float(Rotation.x); + data << float(Rotation.y); + data << float(Rotation.z); + data << float(Rotation.w); +} + +void ForceSetAreaTriggerPositionAndRotation::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + data << TriggerGUID; + data << Position; + data << float(Rotation.x); + data << float(Rotation.y); + data << float(Rotation.z); + data << float(Rotation.w); +} + +bool ForceSetAreaTriggerPositionAndRotation::operator==(ForceSetAreaTriggerPositionAndRotation const& right) const +{ + return TriggerGUID == right.TriggerGUID + && Position == right.Position + && Rotation == right.Rotation; +} + +void AreaTriggerSplineCalculator::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data.WriteBits(Points.size(), 16); + data.WriteBit(Catmullrom); + for (uint32 i = 0; i < Points.size(); ++i) + { + data << Points[i]; + } + data.FlushBits(); +} + +void AreaTriggerSplineCalculator::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(Catmullrom); + } + if (changesMask[2]) + { + if (!ignoreChangesMask) + Points.WriteUpdateMask(data, 16); + else + WriteCompleteDynamicFieldUpdateMask(Points.size(), data, 16); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + for (uint32 i = 0; i < Points.size(); ++i) + { + if (Points.HasChanged(i) || ignoreChangesMask) + { + data << Points[i]; + } + } + } + } + data.FlushBits(); +} + +void AreaTriggerSplineCalculator::ClearChangesMask() +{ + Base::ClearChangesMask(Catmullrom); + Base::ClearChangesMask(Points); + _changesMask.ResetAll(); +} + +void AreaTriggerOrbit::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << *Center; + data << float(Radius); + data << float(InitialAngle); + data << float(BlendFromRadius); + data << int32(ExtraTimeForBlending); + data.WriteBit(CounterClockwise); + data.FlushBits(); +} + +void AreaTriggerOrbit::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteBit(CounterClockwise); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[2]) + { + data << *Center; + } + if (changesMask[3]) + { + data << float(Radius); + } + if (changesMask[4]) + { + data << float(InitialAngle); + } + if (changesMask[5]) + { + data << float(BlendFromRadius); + } + if (changesMask[6]) + { + data << int32(ExtraTimeForBlending); + } + } + data.FlushBits(); +} + +void AreaTriggerOrbit::ClearChangesMask() +{ + Base::ClearChangesMask(CounterClockwise); + Base::ClearChangesMask(Center); + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(InitialAngle); + Base::ClearChangesMask(BlendFromRadius); + Base::ClearChangesMask(ExtraTimeForBlending); + _changesMask.ResetAll(); +} + +void AreaTriggerMovementScript::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << int32(SpellScriptID); + data << *Center; + data << uint32(CreationTime); +} + +void AreaTriggerMovementScript::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger 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 << int32(SpellScriptID); + } + if (changesMask[2]) + { + data << *Center; + } + if (changesMask[3]) + { + data << uint32(CreationTime); + } + } +} + +void AreaTriggerMovementScript::ClearChangesMask() +{ + Base::ClearChangesMask(SpellScriptID); + Base::ClearChangesMask(Center); + Base::ClearChangesMask(CreationTime); + _changesMask.ResetAll(); +} + +void AreaTriggerSphere::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << float(Radius); + data << float(RadiusTarget); +} + +void AreaTriggerSphere::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << float(Radius); + } + if (changesMask[2]) + { + data << float(RadiusTarget); + } + } +} + +void AreaTriggerSphere::ClearChangesMask() +{ + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(RadiusTarget); + _changesMask.ResetAll(); +} + +void AreaTriggerBox::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << *Extents; + data << *ExtentsTarget; +} + +void AreaTriggerBox::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *Extents; + } + if (changesMask[2]) + { + data << *ExtentsTarget; + } + } +} + +void AreaTriggerBox::ClearChangesMask() +{ + Base::ClearChangesMask(Extents); + Base::ClearChangesMask(ExtentsTarget); + _changesMask.ResetAll(); +} + +void AreaTriggerPolygon::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << uint32(Vertices.size()); + data << uint32(VerticesTarget.size()); + data << float(Height); + data << float(HeightTarget); + for (uint32 i = 0; i < Vertices.size(); ++i) + { + data << Vertices[i]; + } + for (uint32 i = 0; i < VerticesTarget.size(); ++i) + { + data << VerticesTarget[i]; + } +} + +void AreaTriggerPolygon::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 5); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Vertices.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Vertices.size(), data); + } + if (changesMask[2]) + { + if (!ignoreChangesMask) + VerticesTarget.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(VerticesTarget.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Vertices.size(); ++i) + { + if (Vertices.HasChanged(i) || ignoreChangesMask) + { + data << Vertices[i]; + } + } + } + if (changesMask[2]) + { + for (uint32 i = 0; i < VerticesTarget.size(); ++i) + { + if (VerticesTarget.HasChanged(i) || ignoreChangesMask) + { + data << VerticesTarget[i]; + } + } + } + if (changesMask[3]) + { + data << float(Height); + } + if (changesMask[4]) + { + data << float(HeightTarget); + } + } +} + +void AreaTriggerPolygon::ClearChangesMask() +{ + Base::ClearChangesMask(Vertices); + Base::ClearChangesMask(VerticesTarget); + Base::ClearChangesMask(Height); + Base::ClearChangesMask(HeightTarget); + _changesMask.ResetAll(); +} + +void AreaTriggerCylinder::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << float(Radius); + data << float(RadiusTarget); + data << float(Height); + data << float(HeightTarget); + data << float(LocationZOffset); + data << float(LocationZOffsetTarget); +} + +void AreaTriggerCylinder::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << float(Radius); + } + if (changesMask[2]) + { + data << float(RadiusTarget); + } + if (changesMask[3]) + { + data << float(Height); + } + if (changesMask[4]) + { + data << float(HeightTarget); + } + if (changesMask[5]) + { + data << float(LocationZOffset); + } + if (changesMask[6]) + { + data << float(LocationZOffsetTarget); + } + } +} + +void AreaTriggerCylinder::ClearChangesMask() +{ + Base::ClearChangesMask(Radius); + Base::ClearChangesMask(RadiusTarget); + Base::ClearChangesMask(Height); + Base::ClearChangesMask(HeightTarget); + Base::ClearChangesMask(LocationZOffset); + Base::ClearChangesMask(LocationZOffsetTarget); + _changesMask.ResetAll(); +} + +void AreaTriggerDisk::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << float(InnerRadius); + data << float(InnerRadiusTarget); + data << float(OuterRadius); + data << float(OuterRadiusTarget); + data << float(Height); + data << float(HeightTarget); + data << float(LocationZOffset); + data << float(LocationZOffsetTarget); +} + +void AreaTriggerDisk::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 9); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << float(InnerRadius); + } + if (changesMask[2]) + { + data << float(InnerRadiusTarget); + } + if (changesMask[3]) + { + data << float(OuterRadius); + } + if (changesMask[4]) + { + data << float(OuterRadiusTarget); + } + if (changesMask[5]) + { + data << float(Height); + } + if (changesMask[6]) + { + data << float(HeightTarget); + } + if (changesMask[7]) + { + data << float(LocationZOffset); + } + if (changesMask[8]) + { + data << float(LocationZOffsetTarget); + } + } +} + +void AreaTriggerDisk::ClearChangesMask() +{ + Base::ClearChangesMask(InnerRadius); + Base::ClearChangesMask(InnerRadiusTarget); + Base::ClearChangesMask(OuterRadius); + Base::ClearChangesMask(OuterRadiusTarget); + Base::ClearChangesMask(Height); + Base::ClearChangesMask(HeightTarget); + Base::ClearChangesMask(LocationZOffset); + Base::ClearChangesMask(LocationZOffsetTarget); + _changesMask.ResetAll(); +} + +void AreaTriggerBoundedPlane::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +{ + data << *Extents; + data << *ExtentsTarget; +} + +void AreaTriggerBoundedPlane::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << *Extents; + } + if (changesMask[2]) + { + data << *ExtentsTarget; + } + } +} + +void AreaTriggerBoundedPlane::ClearChangesMask() +{ + Base::ClearChangesMask(Extents); + Base::ClearChangesMask(ExtentsTarget); + _changesMask.ResetAll(); +} + void AreaTriggerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const { OverrideScaleCurve->WriteCreate(data, owner, receiver); @@ -7059,20 +7813,72 @@ void AreaTriggerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi data << float(BoundsRadius2D); data << uint32(DecalPropertiesID); data << *CreatingEffectGUID; - data << uint32(NumUnitsInside); - data << uint32(NumPlayersInside); data << *OrbitPathTarget; data << *RollPitchYaw; data << int32(PositionalSoundKitID); + data << uint32(MovementStartTime); + data << uint32(CreationTime); + data << float(ZOffset); + data << uint32(Flags); + data << uint32(ScaleCurveId); + data << uint32(FacingCurveId); + data << uint32(MorphCurveId); + data << uint32(MoveCurveId); + data << float(Facing); + data << int32(PathType); + data << uint8(ShapeType); + if (PathType == 3) + { + PathData.Get<UF::AreaTriggerMovementScript>()->WriteCreate(data, owner, receiver); + } + if (ShapeType == 0) + { + ShapeData.Get<UF::AreaTriggerSphere>()->WriteCreate(data, owner, receiver); + } + if (ShapeType == 1) + { + ShapeData.Get<UF::AreaTriggerBox>()->WriteCreate(data, owner, receiver); + } + if (ShapeType == 3) + { + ShapeData.Get<UF::AreaTriggerPolygon>()->WriteCreate(data, owner, receiver); + } + if (ShapeType == 4) + { + ShapeData.Get<UF::AreaTriggerCylinder>()->WriteCreate(data, owner, receiver); + } + if (ShapeType == 7) + { + ShapeData.Get<UF::AreaTriggerDisk>()->WriteCreate(data, owner, receiver); + } + if (ShapeType == 8) + { + ShapeData.Get<UF::AreaTriggerBoundedPlane>()->WriteCreate(data, owner, receiver); + } ExtraScaleCurve->WriteCreate(data, owner, receiver); data.FlushBits(); - data.WriteBit(HeightIgnoresScale); - data.WriteBit(Field_261); + data.WriteBits(TargetRollPitchYaw.has_value(), 1); + data.WriteBits(ForcedPositionAndRotation.has_value(), 1); OverrideMoveCurveX->WriteCreate(data, owner, receiver); + if (TargetRollPitchYaw.has_value()) + { + data << *TargetRollPitchYaw; + } + if (ForcedPositionAndRotation.has_value()) + { + ForcedPositionAndRotation->WriteCreate(data, owner, receiver); + } OverrideMoveCurveY->WriteCreate(data, owner, receiver); OverrideMoveCurveZ->WriteCreate(data, owner, receiver); VisualAnim->WriteCreate(data, owner, receiver); - data.FlushBits(); + if (PathType == 0) + { + PathData.Get<UF::AreaTriggerSplineCalculator>()->WriteCreate(data, owner, receiver); + } + if (PathType == 1) + { + PathData.Get<UF::AreaTriggerOrbit>()->WriteCreate(data, owner, receiver); + } } void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const @@ -7082,122 +7888,232 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const { - data.WriteBits(changesMask.GetBlock(0), 26); + data << uint32(changesMask.GetBlock(0)); + data.WriteBits(changesMask.GetBlock(1), 4); + data.FlushBits(); if (changesMask[0]) { if (changesMask[1]) { - data.WriteBit(HeightIgnoresScale); + OverrideScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[2]) + if (changesMask[6]) { - data.WriteBit(Field_261); + data << *Caster; } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[3]) + if (changesMask[7]) { - OverrideScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << uint32(Duration); } if (changesMask[8]) { - data << *Caster; + data << uint32(TimeToTarget); } if (changesMask[9]) { - data << uint32(Duration); + data << uint32(TimeToTargetScale); } if (changesMask[10]) { - data << uint32(TimeToTarget); + data << uint32(TimeToTargetExtraScale); } if (changesMask[11]) { - data << uint32(TimeToTargetScale); + data << uint32(TimeToTargetPos); } if (changesMask[12]) { - data << uint32(TimeToTargetExtraScale); + data << int32(SpellID); } if (changesMask[13]) { - data << uint32(TimeToTargetPos); + data << int32(SpellForVisuals); } if (changesMask[14]) { - data << int32(SpellID); + SpellVisual->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[15]) { - data << int32(SpellForVisuals); + data << float(BoundsRadius2D); } if (changesMask[16]) { - SpellVisual->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << uint32(DecalPropertiesID); } if (changesMask[17]) { - data << float(BoundsRadius2D); + data << *CreatingEffectGUID; } if (changesMask[18]) { - data << uint32(DecalPropertiesID); + data << *OrbitPathTarget; } if (changesMask[19]) { - data << *CreatingEffectGUID; + data << *RollPitchYaw; } if (changesMask[20]) { - data << uint32(NumUnitsInside); + data << int32(PositionalSoundKitID); } if (changesMask[21]) { - data << uint32(NumPlayersInside); + data << uint32(MovementStartTime); } if (changesMask[22]) { - data << *OrbitPathTarget; + data << uint32(CreationTime); } if (changesMask[23]) { - data << *RollPitchYaw; + data << float(ZOffset); } - if (changesMask[24]) + if (changesMask[25]) { - data << int32(PositionalSoundKitID); + data << uint32(Flags); } - if (changesMask[4]) + if (changesMask[27]) + { + data << uint32(ScaleCurveId); + } + if (changesMask[28]) + { + data << uint32(FacingCurveId); + } + if (changesMask[29]) + { + data << uint32(MorphCurveId); + } + if (changesMask[30]) + { + data << uint32(MoveCurveId); + } + if (changesMask[31]) + { + data << float(Facing); + } + } + if (changesMask[32]) + { + if (changesMask[34]) + { + data << int32(PathType); + } + if (changesMask[35]) + { + data << uint8(ShapeType); + } + if (changesMask[34]) + { + if (PathType == 3) + { + PathData.Get<UF::AreaTriggerMovementScript>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + if (changesMask[35]) + { + if (ShapeType == 0) + { + ShapeData.Get<UF::AreaTriggerSphere>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (ShapeType == 1) + { + ShapeData.Get<UF::AreaTriggerBox>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (ShapeType == 3) + { + ShapeData.Get<UF::AreaTriggerPolygon>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (ShapeType == 4) + { + ShapeData.Get<UF::AreaTriggerCylinder>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (ShapeType == 7) + { + ShapeData.Get<UF::AreaTriggerDisk>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (ShapeType == 8) + { + ShapeData.Get<UF::AreaTriggerBoundedPlane>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[0]) + { + if (changesMask[2]) { ExtraScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[5]) + } + data.FlushBits(); + if (changesMask[0]) + { + data.WriteBits(TargetRollPitchYaw.has_value(), 1); + } + if (changesMask[32]) + { + data.WriteBits(ForcedPositionAndRotation.has_value(), 1); + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[3]) { OverrideMoveCurveX->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[6]) + if (changesMask[24]) + { + if (TargetRollPitchYaw.has_value()) + { + data << *TargetRollPitchYaw; + } + } + } + if (changesMask[32]) + { + if (changesMask[33]) + { + if (ForcedPositionAndRotation.has_value()) + { + ForcedPositionAndRotation->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[0]) + { + if (changesMask[4]) { OverrideMoveCurveY->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[7]) + if (changesMask[5]) { OverrideMoveCurveZ->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[25]) + if (changesMask[26]) { VisualAnim->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - data.FlushBits(); + if (changesMask[32]) + { + if (changesMask[34]) + { + if (PathType == 0) + { + PathData.Get<UF::AreaTriggerSplineCalculator>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (PathType == 1) + { + PathData.Get<UF::AreaTriggerOrbit>()->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } } void AreaTriggerData::ClearChangesMask() { - Base::ClearChangesMask(HeightIgnoresScale); - Base::ClearChangesMask(Field_261); Base::ClearChangesMask(OverrideScaleCurve); Base::ClearChangesMask(ExtraScaleCurve); Base::ClearChangesMask(OverrideMoveCurveX); @@ -7215,12 +8131,25 @@ void AreaTriggerData::ClearChangesMask() Base::ClearChangesMask(BoundsRadius2D); Base::ClearChangesMask(DecalPropertiesID); Base::ClearChangesMask(CreatingEffectGUID); - Base::ClearChangesMask(NumUnitsInside); - Base::ClearChangesMask(NumPlayersInside); Base::ClearChangesMask(OrbitPathTarget); Base::ClearChangesMask(RollPitchYaw); Base::ClearChangesMask(PositionalSoundKitID); + Base::ClearChangesMask(MovementStartTime); + Base::ClearChangesMask(CreationTime); + Base::ClearChangesMask(ZOffset); + Base::ClearChangesMask(TargetRollPitchYaw); + Base::ClearChangesMask(Flags); Base::ClearChangesMask(VisualAnim); + Base::ClearChangesMask(ScaleCurveId); + Base::ClearChangesMask(FacingCurveId); + Base::ClearChangesMask(MorphCurveId); + Base::ClearChangesMask(MoveCurveId); + Base::ClearChangesMask(Facing); + Base::ClearChangesMask(ForcedPositionAndRotation); + Base::ClearChangesMask(PathType); + Base::ClearChangesMask(ShapeType); + Base::ClearChangesMask(PathData); + Base::ClearChangesMask(ShapeData); _changesMask.ResetAll(); } diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 6635950cc62..db0f1859545 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -227,6 +227,8 @@ struct UnitChannel : public IsUpdateFieldStructureTag { int32 SpellID; UF::SpellCastVisual SpellVisual; + uint32 StartTimeMs; + uint32 Duration; void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const; @@ -258,7 +260,18 @@ struct PassiveSpellHistory : public IsUpdateFieldStructureTag bool operator!=(PassiveSpellHistory const& right) const { return !(*this == right); } }; -struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<222> +struct UnitAssistActionData : public IsUpdateFieldStructureTag, public HasChangesMask<4> +{ + UpdateField<uint8, 0, 1> Type; + UpdateField<std::string, 0, 2> PlayerName; + UpdateField<uint32, 0, 3> VirtualRealmAddress; + + void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<223> { UpdateField<bool, 0, 1> Field_314; UpdateField<std::vector<uint32>, 0, 2> StateWorldEffectIDs; @@ -406,19 +419,20 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<222> 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 - UpdateFieldArray<int32, 10, 135, 136> Power; - UpdateFieldArray<int32, 10, 135, 146> MaxPower; - UpdateFieldArray<float, 10, 135, 156> PowerRegenFlatModifier; - UpdateFieldArray<float, 10, 135, 166> PowerRegenInterruptedFlatModifier; - UpdateFieldArray<UF::VisibleItem, 3, 176, 177> VirtualItems; - UpdateFieldArray<uint32, 2, 180, 181> AttackRoundBaseTime; - UpdateFieldArray<int32, 4, 183, 184> Stats; - UpdateFieldArray<int32, 4, 183, 188> StatPosBuff; - UpdateFieldArray<int32, 4, 183, 192> StatNegBuff; - UpdateFieldArray<int32, 4, 183, 196> StatSupportBuff; - UpdateFieldArray<int32, 7, 200, 201> Resistances; - UpdateFieldArray<int32, 7, 200, 208> BonusResistanceMods; - UpdateFieldArray<int32, 7, 200, 215> ManaCostModifier; + 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; 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; @@ -499,6 +513,25 @@ struct CTROptions : public IsUpdateFieldStructureTag bool operator!=(CTROptions const& right) const { return !(*this == right); } }; +struct LeaverInfo : public IsUpdateFieldStructureTag +{ + ObjectGuid BnetAccountGUID; + float LeaveScore; + uint32 SeasonID; + uint32 TotalLeaves; + uint32 TotalSuccesses; + int32 ConsecutiveSuccesses; + int64 LastPenaltyTime; + int64 LeaverExpirationTime; + int32 Unknown_1120; + uint32 LeaverStatus; + + 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==(LeaverInfo const& right) const; + bool operator!=(LeaverInfo const& right) const { return !(*this == right); } +}; + struct DeclinedNames : public IsUpdateFieldStructureTag, public HasChangesMask<6> { UpdateFieldArray<std::string, 5, 0, 1> Name; @@ -521,7 +554,7 @@ struct CustomTabardInfo : public IsUpdateFieldStructureTag, public HasChangesMas void ClearChangesMask(); }; -struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<322> +struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<324> { UpdateField<bool, 0, 1> HasQuestSession; UpdateField<bool, 0, 2> HasLevelLink; @@ -551,29 +584,31 @@ struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<322> UpdateField<int32, 0, 26> FakeInebriation; UpdateField<uint32, 0, 27> VirtualPlayerRealm; UpdateField<uint32, 0, 28> CurrentSpecID; - UpdateField<int32, 0, 29> TaxiMountAnimKitID; - UpdateField<uint8, 0, 30> CurrentBattlePetBreedQuality; - UpdateField<int32, 0, 31> HonorLevel; - UpdateField<int64, 32, 33> LogoutTime; - UpdateField<std::string, 32, 34> Name; - UpdateField<int32, 32, 35> Field_1AC; - UpdateField<int32, 32, 36> Field_1B0; - UpdateField<int32, 32, 37> CurrentBattlePetSpeciesID; - UpdateField<UF::CTROptions, 32, 38> CtrOptions; - UpdateField<int32, 32, 39> CovenantID; - UpdateField<int32, 32, 40> SoulbindID; - UpdateField<WorldPackets::MythicPlus::DungeonScoreSummary, 32, 41> DungeonScore; - UpdateField<ObjectGuid, 32, 42> SpectateTarget; - UpdateField<int32, 32, 43> Field_200; - OptionalUpdateField<UF::DeclinedNames, 32, 44> DeclinedNames; - UpdateField<UF::CustomTabardInfo, 32, 45> PersonalTabard; - UpdateFieldArray<uint8, 2, 46, 47> PartyType; - UpdateFieldArray<UF::QuestLog, 175, 49, 50> QuestLog; - UpdateFieldArray<UF::VisibleItem, 19, 225, 226> VisibleItems; - UpdateFieldArray<float, 6, 245, 246> AvgItemLevel; - UpdateFieldArray<UF::ZonePlayerForcedReaction, 32, 252, 253> ForcedReactions; - UpdateFieldArray<WorldPackets::Item::ItemInstance, 16, 285, 286> VisibleEquipableSpells; - UpdateFieldArray<uint32, 19, 302, 303> Field_3120; + UpdateField<int32, 0, 29> CurrentCombatTraitConfigSubTreeID; + UpdateField<int32, 0, 30> TaxiMountAnimKitID; + UpdateField<uint8, 0, 31> CurrentBattlePetBreedQuality; + UpdateField<int32, 32, 33> HonorLevel; + UpdateField<int64, 32, 34> LogoutTime; + UpdateField<std::string, 32, 35> Name; + UpdateField<int32, 32, 36> Field_1AC; + UpdateField<int32, 32, 37> Field_1B0; + UpdateField<int32, 32, 38> CurrentBattlePetSpeciesID; + UpdateField<UF::CTROptions, 32, 39> CtrOptions; + UpdateField<int32, 32, 40> CovenantID; + UpdateField<int32, 32, 41> SoulbindID; + UpdateField<WorldPackets::MythicPlus::DungeonScoreSummary, 32, 42> DungeonScore; + UpdateField<UF::LeaverInfo, 32, 43> LeaverInfo; + UpdateField<ObjectGuid, 32, 44> SpectateTarget; + UpdateField<int32, 32, 45> Field_200; + OptionalUpdateField<UF::DeclinedNames, 32, 46> DeclinedNames; + UpdateField<UF::CustomTabardInfo, 32, 47> PersonalTabard; + UpdateFieldArray<uint8, 2, 48, 49> PartyType; + UpdateFieldArray<UF::QuestLog, 175, 51, 52> QuestLog; + UpdateFieldArray<UF::VisibleItem, 19, 227, 228> VisibleItems; + UpdateFieldArray<float, 6, 247, 248> AvgItemLevel; + UpdateFieldArray<UF::ZonePlayerForcedReaction, 32, 254, 255> ForcedReactions; + UpdateFieldArray<WorldPackets::Item::ItemInstance, 16, 287, 288> VisibleEquipableSpells; + UpdateFieldArray<uint32, 19, 304, 305> Field_3120; 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; @@ -791,6 +826,7 @@ struct TraitEntry : public IsUpdateFieldStructureTag int32 TraitNodeEntryID; int32 Rank; int32 GrantedRanks; + int32 BonusRanks; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; @@ -1025,6 +1061,24 @@ struct DelveData : public IsUpdateFieldStructureTag bool operator!=(DelveData const& right) const { return !(*this == right); } }; +struct ChallengeModeData : public IsUpdateFieldStructureTag +{ + int32 Unknown_1120_1; + int32 Unknown_1120_2; + uint64 Unknown_1120_3; + int64 Unknown_1120_4; + ObjectGuid KeystoneOwnerGUID; + ObjectGuid LeaverGUID; + uint32 IsActive; + uint32 HasRestrictions; + uint32 CanVoteAbandon; + + 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==(ChallengeModeData const& right) const; + bool operator!=(ChallengeModeData const& right) const { return !(*this == right); } +}; + struct Research : public IsUpdateFieldStructureTag { int16 ResearchProjectID; @@ -1035,7 +1089,7 @@ struct Research : public IsUpdateFieldStructureTag bool operator!=(Research const& right) const { return !(*this == right); } }; -struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<517> +struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<385> { UpdateField<bool, 0, 1> BackpackAutoSortDisabled; UpdateField<bool, 0, 2> BackpackSellJunkDisabled; @@ -1043,9 +1097,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, 43, 44> ResearchSites; + UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 45, 46> ResearchSiteProgress; + UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 47, 48> Research; DynamicUpdateField<uint64, 0, 7> KnownTitles; DynamicUpdateField<UF::PlayerDataElement, 0, 8> CharacterDataElements; DynamicUpdateField<UF::PlayerDataElement, 0, 9> AccountDataElements; @@ -1079,119 +1133,121 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas DynamicUpdateField<UF::CharacterRestriction, 0, 24> CharacterRestrictions; DynamicUpdateField<UF::TraitConfig, 32, 34> TraitConfigs; DynamicUpdateField<UF::CraftingOrder, 32, 35> CraftingOrders; - 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> NumAccountBankTabs; - UpdateField<UF::ResearchHistory, 102, 125> ResearchHistory; - UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 102, 126> FrozenPerksVendorItem; - UpdateField<UF::ActivePlayerUnk901, 102, 128> Field_1410; - OptionalUpdateField<UF::QuestSession, 102, 127> QuestSession; - UpdateField<int32, 102, 129> UiChromieTimeExpansionID; - UpdateField<int32, 102, 130> TimerunningSeasonID; - UpdateField<int32, 102, 131> TransportServerTime; - UpdateField<uint32, 102, 132> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin - UpdateField<int16, 102, 133> DEBUGSoulbindConduitRank; - UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 134, 135> DungeonScore; - UpdateField<uint32, 134, 136> ActiveCombatTraitConfigID; - UpdateField<int32, 134, 137> ItemUpgradeHighOnehandWeaponItemID; - UpdateField<int32, 134, 138> ItemUpgradeHighFingerItemID; - UpdateField<float, 134, 139> ItemUpgradeHighFingerWatermark; - UpdateField<int32, 134, 140> ItemUpgradeHighTrinketItemID; - UpdateField<float, 134, 141> ItemUpgradeHighTrinketWatermark; - UpdateField<uint64, 134, 142> LootHistoryInstanceID; - OptionalUpdateField<UF::StableInfo, 134, 143> PetStable; - UpdateField<uint8, 134, 144> RequiredMountCapabilityFlags; - OptionalUpdateField<UF::WalkInData, 134, 145> WalkInData; - OptionalUpdateField<UF::DelveData, 134, 146> DelveData; - UpdateFieldArray<ObjectGuid, 232, 147, 148> InvSlots; - UpdateFieldArray<UF::RestInfo, 2, 380, 381> RestInfo; - UpdateFieldArray<int32, 7, 383, 384> ModDamageDonePos; - UpdateFieldArray<int32, 7, 383, 391> ModDamageDoneNeg; - UpdateFieldArray<float, 7, 383, 398> ModDamageDonePercent; - UpdateFieldArray<float, 7, 383, 405> ModHealingDonePercent; - UpdateFieldArray<float, 3, 412, 413> WeaponDmgMultipliers; - UpdateFieldArray<float, 3, 412, 416> WeaponAtkSpeedMultipliers; - UpdateFieldArray<uint32, 12, 419, 420> BuybackPrice; - UpdateFieldArray<int64, 12, 419, 432> BuybackTimestamp; - UpdateFieldArray<int32, 32, 444, 445> CombatRatings; - UpdateFieldArray<uint32, 4, 477, 478> NoReagentCostMask; - UpdateFieldArray<int32, 2, 482, 483> ProfessionSkillLine; - UpdateFieldArray<uint32, 5, 485, 486> BagSlotFlags; - UpdateFieldArray<uint32, 7, 491, 492> BankBagSlotFlags; - UpdateFieldArray<float, 17, 499, 500> ItemUpgradeHighWatermark; + DynamicUpdateField<UF::BankTabSettings, 32, 41> CharacterBankTabSettings; + DynamicUpdateField<UF::BankTabSettings, 32, 42> AccountBankTabSettings; + UpdateField<ObjectGuid, 32, 49> FarsightObject; + UpdateField<ObjectGuid, 32, 50> SummonedBattlePetGUID; + UpdateField<uint64, 32, 51> Coinage; + UpdateField<uint64, 32, 52> AccountBankCoinage; + UpdateField<int32, 32, 53> XP; + UpdateField<int32, 32, 54> NextLevelXP; + UpdateField<int32, 32, 55> TrialXP; + UpdateField<UF::SkillInfo, 32, 56> Skill; + UpdateField<int32, 32, 57> CharacterPoints; + UpdateField<int32, 32, 58> MaxTalentTiers; + UpdateField<uint32, 32, 59> TrackCreatureMask; + UpdateField<float, 32, 60> MainhandExpertise; + UpdateField<float, 32, 61> OffhandExpertise; + UpdateField<float, 32, 62> RangedExpertise; + UpdateField<float, 32, 63> CombatRatingExpertise; + UpdateField<float, 32, 64> BlockPercentage; + UpdateField<float, 32, 65> DodgePercentage; + UpdateField<float, 32, 66> DodgePercentageFromAttribute; + UpdateField<float, 32, 67> ParryPercentage; + UpdateField<float, 32, 68> ParryPercentageFromAttribute; + UpdateField<float, 32, 69> CritPercentage; + UpdateField<float, 70, 71> RangedCritPercentage; + UpdateField<float, 70, 72> OffhandCritPercentage; + UpdateField<float, 70, 73> SpellCritPercentage; + UpdateField<int32, 70, 74> ShieldBlock; + UpdateField<float, 70, 75> ShieldBlockCritPercentage; + UpdateField<float, 70, 76> Mastery; + UpdateField<float, 70, 77> Speed; + UpdateField<float, 70, 78> Avoidance; + UpdateField<float, 70, 79> Sturdiness; + UpdateField<int32, 70, 80> Versatility; + UpdateField<float, 70, 81> VersatilityBonus; + UpdateField<float, 70, 82> PvpPowerDamage; + UpdateField<float, 70, 83> PvpPowerHealing; + UpdateField<UF::BitVectors, 70, 84> BitVectors; + UpdateField<int32, 70, 85> ModHealingDonePos; + UpdateField<float, 70, 86> ModHealingPercent; + UpdateField<float, 70, 87> ModPeriodicHealingDonePercent; + UpdateField<float, 70, 88> ModSpellPowerPercent; + UpdateField<float, 70, 89> ModResiliencePercent; + UpdateField<float, 70, 90> OverrideSpellPowerByAPPercent; + UpdateField<float, 70, 91> OverrideAPBySpellPowerPercent; + UpdateField<int32, 70, 92> ModTargetResistance; + UpdateField<int32, 70, 93> ModTargetPhysicalResistance; + UpdateField<uint32, 70, 94> LocalFlags; + UpdateField<uint8, 70, 95> GrantableLevels; + UpdateField<uint8, 70, 96> MultiActionBars; + UpdateField<uint8, 70, 97> LifetimeMaxRank; + UpdateField<uint8, 70, 98> NumRespecs; + UpdateField<uint32, 70, 99> PvpMedals; + UpdateField<uint16, 70, 100> TodayHonorableKills; + UpdateField<uint16, 70, 101> YesterdayHonorableKills; + UpdateField<uint32, 102, 103> LifetimeHonorableKills; + UpdateField<int32, 102, 104> WatchedFactionIndex; + UpdateField<int32, 102, 105> MaxLevel; + UpdateField<int32, 102, 106> ScalingPlayerLevelDelta; + UpdateField<int32, 102, 107> MaxCreatureScalingLevel; + UpdateField<int32, 102, 108> PetSpellPower; + UpdateField<float, 102, 109> UiHitModifier; + UpdateField<float, 102, 110> UiSpellHitModifier; + UpdateField<int32, 102, 111> HomeRealmTimeOffset; + UpdateField<float, 102, 112> ModPetHaste; + UpdateField<int8, 102, 113> JailersTowerLevelMax; + UpdateField<int8, 102, 114> JailersTowerLevel; + UpdateField<uint8, 102, 115> LocalRegenFlags; + UpdateField<uint8, 102, 116> AuraVision; + UpdateField<uint8, 102, 117> NumBackpackSlots; + UpdateField<int32, 102, 118> OverrideSpellsID; + UpdateField<uint16, 102, 119> LootSpecID; + UpdateField<uint32, 102, 120> OverrideZonePVPType; + UpdateField<int32, 102, 121> Honor; + UpdateField<int32, 102, 122> HonorNextLevel; + UpdateField<int32, 102, 123> PerksProgramCurrency; + UpdateField<uint8, 102, 124> NumBankSlots; + UpdateField<uint8, 102, 125> NumCharacterBankTabs; + UpdateField<uint8, 102, 126> NumAccountBankTabs; + UpdateField<UF::ResearchHistory, 102, 127> ResearchHistory; + UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 102, 128> FrozenPerksVendorItem; + UpdateField<UF::ActivePlayerUnk901, 102, 130> Field_1410; + OptionalUpdateField<UF::QuestSession, 102, 129> QuestSession; + UpdateField<int32, 102, 131> UiChromieTimeExpansionID; + UpdateField<int32, 102, 132> TimerunningSeasonID; + UpdateField<int32, 102, 133> TransportServerTime; + UpdateField<uint32, 134, 135> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin + UpdateField<int16, 134, 136> DEBUGSoulbindConduitRank; + UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 134, 137> DungeonScore; + 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; 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; @@ -1199,7 +1255,22 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas void ClearChangesMask(); }; -struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<25> +struct GameObjectAssistActionData : public IsUpdateFieldStructureTag +{ + std::string PlayerName; + std::string MonsterName; + uint32 VirtualRealmAddress; + uint8 Sex; + int64 Time; + int32 DelveTier; + + void WriteCreate(ByteBuffer& data, GameObject const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, GameObject const* owner, Player const* receiver) const; + bool operator==(GameObjectAssistActionData const& right) const; + bool operator!=(GameObjectAssistActionData const& right) const { return !(*this == right); } +}; + +struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<26> { UpdateField<std::vector<uint32>, 0, 1> StateWorldEffectIDs; struct StateWorldEffectIDsTag : ViewerDependentValueTag<std::vector<uint32>> {}; @@ -1232,6 +1303,7 @@ struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask< UpdateField<uint32, 0, 22> UiWidgetItemID; UpdateField<uint32, 0, 23> UiWidgetItemQuality; UpdateField<uint32, 0, 24> UiWidgetItemUnknown1000; + OptionalUpdateField<UF::GameObjectAssistActionData, 0, 25> AssistActionData; 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; @@ -1300,33 +1372,163 @@ struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5> void ClearChangesMask(); }; -struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<26> -{ - UpdateField<bool, 0, 1> HeightIgnoresScale; - UpdateField<bool, 0, 2> Field_261; - UpdateField<UF::ScaleCurve, 0, 3> OverrideScaleCurve; - UpdateField<UF::ScaleCurve, 0, 4> ExtraScaleCurve; - UpdateField<UF::ScaleCurve, 0, 5> OverrideMoveCurveX; - UpdateField<UF::ScaleCurve, 0, 6> OverrideMoveCurveY; - UpdateField<UF::ScaleCurve, 0, 7> OverrideMoveCurveZ; - UpdateField<ObjectGuid, 0, 8> Caster; - UpdateField<uint32, 0, 9> Duration; - UpdateField<uint32, 0, 10> TimeToTarget; - UpdateField<uint32, 0, 11> TimeToTargetScale; - UpdateField<uint32, 0, 12> TimeToTargetExtraScale; - UpdateField<uint32, 0, 13> TimeToTargetPos; // Linked to m_overrideMoveCurve - UpdateField<int32, 0, 14> SpellID; - UpdateField<int32, 0, 15> SpellForVisuals; - UpdateField<UF::SpellCastVisual, 0, 16> SpellVisual; - UpdateField<float, 0, 17> BoundsRadius2D; - UpdateField<uint32, 0, 18> DecalPropertiesID; - UpdateField<ObjectGuid, 0, 19> CreatingEffectGUID; - UpdateField<uint32, 0, 20> NumUnitsInside; - UpdateField<uint32, 0, 21> NumPlayersInside; // When not 0 this causes SpellVisualEvent 14 to trigger, playing alternate visuals, typically used by "SOAK THIS" areatriggers - UpdateField<ObjectGuid, 0, 22> OrbitPathTarget; - UpdateField<TaggedPosition<Position::XYZ>, 0, 23> RollPitchYaw; - UpdateField<int32, 0, 24> PositionalSoundKitID; - UpdateField<UF::VisualAnim, 0, 25> VisualAnim; +struct ForceSetAreaTriggerPositionAndRotation : public IsUpdateFieldStructureTag +{ + ObjectGuid TriggerGUID; + TaggedPosition<::Position::XYZ> Position; + QuaternionData Rotation; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + bool operator==(ForceSetAreaTriggerPositionAndRotation const& right) const; + bool operator!=(ForceSetAreaTriggerPositionAndRotation const& right) const { return !(*this == right); } +}; + +struct AreaTriggerSplineCalculator : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + UpdateField<bool, 0, 1> Catmullrom; + DynamicUpdateField<TaggedPosition<Position::XYZ>, 0, 2> Points; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerOrbit : public IsUpdateFieldStructureTag, public HasChangesMask<7> +{ + UpdateField<bool, 0, 1> CounterClockwise; + UpdateField<TaggedPosition<Position::XYZ>, 0, 2> Center; + UpdateField<float, 0, 3> Radius; + UpdateField<float, 0, 4> InitialAngle; + UpdateField<float, 0, 5> BlendFromRadius; + UpdateField<int32, 0, 6> ExtraTimeForBlending; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerMovementScript : public IsUpdateFieldStructureTag, public HasChangesMask<4> +{ + UpdateField<int32, 0, 1> SpellScriptID; + UpdateField<TaggedPosition<Position::XYZ>, 0, 2> Center; + UpdateField<uint32, 0, 3> CreationTime; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerSphere : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + UpdateField<float, 0, 1> Radius; + UpdateField<float, 0, 2> RadiusTarget; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerBox : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + UpdateField<TaggedPosition<Position::XYZ>, 0, 1> Extents; + UpdateField<TaggedPosition<Position::XYZ>, 0, 2> ExtentsTarget; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerPolygon : public IsUpdateFieldStructureTag, public HasChangesMask<5> +{ + DynamicUpdateField<TaggedPosition<Position::XY>, 0, 1> Vertices; + DynamicUpdateField<TaggedPosition<Position::XY>, 0, 2> VerticesTarget; + UpdateField<float, 0, 3> Height; + UpdateField<float, 0, 4> HeightTarget; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerCylinder : public IsUpdateFieldStructureTag, public HasChangesMask<7> +{ + UpdateField<float, 0, 1> Radius; + UpdateField<float, 0, 2> RadiusTarget; + UpdateField<float, 0, 3> Height; + UpdateField<float, 0, 4> HeightTarget; + UpdateField<float, 0, 5> LocationZOffset; + UpdateField<float, 0, 6> LocationZOffsetTarget; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerDisk : public IsUpdateFieldStructureTag, public HasChangesMask<9> +{ + UpdateField<float, 0, 1> InnerRadius; + UpdateField<float, 0, 2> InnerRadiusTarget; + UpdateField<float, 0, 3> OuterRadius; + UpdateField<float, 0, 4> OuterRadiusTarget; + UpdateField<float, 0, 5> Height; + UpdateField<float, 0, 6> HeightTarget; + UpdateField<float, 0, 7> LocationZOffset; + UpdateField<float, 0, 8> LocationZOffsetTarget; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerBoundedPlane : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + UpdateField<TaggedPosition<Position::XY>, 0, 1> Extents; + UpdateField<TaggedPosition<Position::XY>, 0, 2> ExtentsTarget; + + void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; + void ClearChangesMask(); +}; + +struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<36> +{ + UpdateField<UF::ScaleCurve, 0, 1> OverrideScaleCurve; + UpdateField<UF::ScaleCurve, 0, 2> ExtraScaleCurve; + UpdateField<UF::ScaleCurve, 0, 3> OverrideMoveCurveX; + UpdateField<UF::ScaleCurve, 0, 4> OverrideMoveCurveY; + UpdateField<UF::ScaleCurve, 0, 5> OverrideMoveCurveZ; + UpdateField<ObjectGuid, 0, 6> Caster; + UpdateField<uint32, 0, 7> Duration; + UpdateField<uint32, 0, 8> TimeToTarget; + UpdateField<uint32, 0, 9> TimeToTargetScale; + UpdateField<uint32, 0, 10> TimeToTargetExtraScale; + UpdateField<uint32, 0, 11> TimeToTargetPos; // Linked to m_overrideMoveCurve + UpdateField<int32, 0, 12> SpellID; + UpdateField<int32, 0, 13> SpellForVisuals; + UpdateField<UF::SpellCastVisual, 0, 14> SpellVisual; + UpdateField<float, 0, 15> BoundsRadius2D; + UpdateField<uint32, 0, 16> DecalPropertiesID; + UpdateField<ObjectGuid, 0, 17> CreatingEffectGUID; + UpdateField<ObjectGuid, 0, 18> OrbitPathTarget; + UpdateField<TaggedPosition<Position::XYZ>, 0, 19> RollPitchYaw; + UpdateField<int32, 0, 20> PositionalSoundKitID; + UpdateField<uint32, 0, 21> MovementStartTime; + UpdateField<uint32, 0, 22> CreationTime; + UpdateField<float, 0, 23> ZOffset; + OptionalUpdateField<TaggedPosition<Position::XYZ>, 0, 24> TargetRollPitchYaw; + UpdateField<uint32, 0, 25> Flags; + UpdateField<UF::VisualAnim, 0, 26> VisualAnim; + UpdateField<uint32, 0, 27> ScaleCurveId; + UpdateField<uint32, 0, 28> FacingCurveId; + UpdateField<uint32, 0, 29> MorphCurveId; + UpdateField<uint32, 0, 30> MoveCurveId; + UpdateField<float, 0, 31> Facing; + OptionalUpdateField<UF::ForceSetAreaTriggerPositionAndRotation, 32, 33> ForcedPositionAndRotation; + UpdateField<int32, 32, 34> PathType; + UpdateField<uint8, 32, 35> ShapeType; + VariantUpdateField<32, 34, UF::AreaTriggerSplineCalculator, UF::AreaTriggerOrbit, UF::AreaTriggerMovementScript> PathData; + VariantUpdateField<32, 35, UF::AreaTriggerSphere, UF::AreaTriggerBox, UF::AreaTriggerPolygon, UF::AreaTriggerCylinder, UF::AreaTriggerDisk, UF::AreaTriggerBoundedPlane> ShapeData; 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; |
