aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Object
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-10-10 16:21:55 +0200
committerShauren <shauren.trinity@gmail.com>2025-10-10 16:21:55 +0200
commit53068a94e88991ae7196fb247df4b7ca2e47e554 (patch)
tree42afe6e6160b0317f72ddec25562988145d7a5ff /src/server/game/Entities/Object
parenta7d825c6deb2711392956abac2d494a8731f58c3 (diff)
Core: Updated to 11.2.5.63704
Diffstat (limited to 'src/server/game/Entities/Object')
-rw-r--r--src/server/game/Entities/Object/Object.h13
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateField.cpp63
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateField.h224
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFieldImpl.h129
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.cpp311
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h208
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateMask.h8
7 files changed, 620 insertions, 336 deletions
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 971b74494e0..e049ca95fae 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -171,6 +171,12 @@ namespace UF
setter.Clear();
}
+ template<typename K, typename V>
+ inline void RemoveMapUpdateFieldValue(MapUpdateFieldSetter<K, V>& setter, std::type_identity_t<K> const& key)
+ {
+ setter.RemoveKey(key);
+ }
+
template<typename T>
inline void RemoveOptionalUpdateFieldValue(OptionalUpdateFieldSetter<T>& setter)
{
@@ -363,6 +369,13 @@ class TC_GAME_API Object
UF::RemoveDynamicUpdateFieldValue(setter, index);
}
+ template<typename K, typename V>
+ void RemoveMapUpdateFieldValue(UF::MapUpdateFieldSetter<K, V> setter, std::type_identity_t<K> const& key)
+ {
+ AddToObjectUpdateIfNeeded();
+ UF::RemoveMapUpdateFieldValue(setter, key);
+ }
+
template<typename T>
void ClearDynamicUpdateFieldValues(UF::DynamicUpdateFieldSetter<T> setter)
{
diff --git a/src/server/game/Entities/Object/Updates/UpdateField.cpp b/src/server/game/Entities/Object/Updates/UpdateField.cpp
deleted file mode 100644
index 2c0527190db..00000000000
--- a/src/server/game/Entities/Object/Updates/UpdateField.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "UpdateField.h"
-#include "ByteBuffer.h"
-
-void UF::WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data, int32 bitsForSize /*= 32*/)
-{
- data.WriteBits(size, bitsForSize);
- if (size > 32)
- {
- if (data.HasUnfinishedBitPack())
- for (std::size_t block = 0; block < size / 32; ++block)
- data.WriteBits(updateMask[block], 32);
- else
- for (std::size_t block = 0; block < size / 32; ++block)
- data << uint32(updateMask[block]);
- }
- else if (size == 32)
- {
- data.WriteBits(updateMask.back(), 32);
- return;
- }
-
- if (size % 32)
- data.WriteBits(updateMask.back(), size % 32);
-}
-
-void UF::WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data, int32 bitsForSize /*= 32*/)
-{
- data.WriteBits(size, bitsForSize);
- if (size > 32)
- {
- if (data.HasUnfinishedBitPack())
- for (std::size_t block = 0; block < size / 32; ++block)
- data.WriteBits(0xFFFFFFFFu, 32);
- else
- for (std::size_t block = 0; block < size / 32; ++block)
- data << uint32(0xFFFFFFFFu);
- }
- else if (size == 32)
- {
- data.WriteBits(0xFFFFFFFFu, 32);
- return;
- }
-
- if (size % 32)
- data.WriteBits(0xFFFFFFFFu, size % 32);
-}
diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h
index 874b38d87d8..8f351f8a37f 100644
--- a/src/server/game/Entities/Object/Updates/UpdateField.h
+++ b/src/server/game/Entities/Object/Updates/UpdateField.h
@@ -18,11 +18,13 @@
#ifndef UpdateField_h__
#define UpdateField_h__
+#include "Concepts.h"
#include "ObjectGuid.h"
#include "Optional.h"
#include "UpdateMask.h"
#include <algorithm>
#include <memory>
+#include <unordered_map>
#include <variant>
#include <vector>
@@ -63,6 +65,12 @@ namespace UF
template<typename T, int32 BlockBit, uint32 Bit>
class DynamicUpdateField;
+ template<typename K, typename V>
+ class MapUpdateFieldBase;
+
+ template<typename K, typename V, int32 BlockBit, uint32 Bit>
+ class MapUpdateField;
+
template<typename T>
class OptionalUpdateFieldBase;
@@ -87,6 +95,13 @@ namespace UF
template<typename T, bool PublicSet>
struct MutableNestedFieldReference;
+ enum class MapUpdateFieldState : uint8
+ {
+ Unchanged = 0,
+ Changed = 1,
+ Deleted = 2
+ };
+
struct IsUpdateFieldStructureTag
{
};
@@ -241,6 +256,25 @@ namespace UF
std::vector<uint32>& _updateMask;
};
+ template<typename K, typename V>
+ struct MapUpdateFieldSetter
+ {
+ template<typename F, typename G>
+ friend void RemoveMapUpdateFieldValue(MapUpdateFieldSetter<F, G>& setter, std::type_identity_t<F> const& key);
+
+ MapUpdateFieldSetter(std::unordered_map<K, V>& values) : _values(values) { }
+
+ private:
+ void RemoveKey(K const& key)
+ {
+ auto itr = _values.find(key);
+ if (itr != _values.end())
+ itr->second.state = MapUpdateFieldState::Deleted;
+ }
+
+ std::unordered_map<K, V>& _values;
+ };
+
template<typename T>
struct OptionalUpdateFieldSetter
{
@@ -334,6 +368,35 @@ namespace UF
return { (_value.*field)._values[index] };
}
+ template<typename K, typename V, int32 BlockBit, uint32 Bit>
+ MapUpdateFieldSetter<K, typename MapUpdateField<K, V, BlockBit, Bit>::mapped_type>
+ ModifyValue(MapUpdateField<K, V, BlockBit, Bit>(T::* field))
+ {
+ if constexpr (BlockBit >= 0)
+ _value._changesMask.Set(BlockBit);
+
+ _value._changesMask.Set(Bit);
+ return { (_value.*field)._values };
+ }
+
+ template<typename K, typename V, int32 BlockBit, uint32 Bit>
+ 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(MapUpdateField<K, V, BlockBit, Bit>(T::* field), std::type_identity_t<K> const& key)
+ {
+ if constexpr (BlockBit >= 0)
+ _value._changesMask.Set(BlockBit);
+
+ _value._changesMask.Set(Bit);
+
+ auto itr = (_value.*field)._values.try_emplace(key).first;
+ itr->second.state = MapUpdateFieldState::Changed;
+ return { itr->second.value };
+ }
+
template<typename V, int32 BlockBit, uint32 Bit>
OptionalUpdateFieldSetter<V> ModifyValue(OptionalUpdateField<V, BlockBit, Bit>(T::* field))
{
@@ -499,6 +562,9 @@ namespace UF
template<typename T>
friend struct DynamicUpdateFieldSetter;
+ template<typename K, typename V>
+ friend struct MapUpdateFieldSetter;
+
template<typename T, bool PublicSet>
friend struct MutableFieldReferenceWithChangesMask;
@@ -545,7 +611,21 @@ namespace UF
}
template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
- void MarkChanged(DynamicUpdateField<T, BlockBit, Bit>(Derived::*), uint32)
+ void MarkChanged(DynamicUpdateField<T, BlockBit, Bit>(Derived::* field), uint32 index)
+ {
+ 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);
+ DynamicUpdateField<T, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field);
+ if (index < uf.size())
+ uf.MarkChanged(index);
+ }
+
+ template<typename Derived, typename K, typename V, int32 BlockBit, uint32 Bit>
+ void MarkChanged(MapUpdateField<K, V, BlockBit, Bit>(Derived::* field), std::type_identity_t<K> const& key)
{
static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
@@ -553,6 +633,10 @@ namespace UF
_changesMask.Set(BlockBit);
_changesMask.Set(Bit);
+ MapUpdateField<K, V, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field);
+ auto itr = uf._values.find(key);
+ if (itr != uf._values.end() && itr->second.state == MapUpdateFieldState::Unchanged)
+ itr->second.state = MapUpdateFieldState::Changed;
}
template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
@@ -602,13 +686,24 @@ namespace UF
template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
void ClearChanged(DynamicUpdateField<T, BlockBit, Bit>(Derived::* field), uint32 index)
{
- _changesMask.Reset(Bit);
+ static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
DynamicUpdateField<T, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field);
if (index < uf.size())
uf.ClearChanged(index);
}
+ template<typename Derived, typename K, typename V, int32 BlockBit, uint32 Bit>
+ void ClearChanged(MapUpdateField<K, V, BlockBit, Bit>(Derived::* field), std::type_identity_t<K> const& key)
+ {
+ static_assert(std::is_base_of_v<Base, Derived>, "Given field argument must belong to the same structure as this HasChangesMask");
+
+ MapUpdateField<K, V, BlockBit, Bit>& uf = (static_cast<Derived*>(this)->*field);
+ auto itr = uf._values.find(key);
+ if (itr != uf._values.end() && itr->second.state == MapUpdateFieldState::Changed)
+ itr->second.state = MapUpdateFieldState::Unchanged;
+ }
+
template<typename Derived, typename T, int32 BlockBit, uint32 Bit>
void ClearChanged(OptionalUpdateField<T, BlockBit, Bit>(Derived::*))
{
@@ -628,23 +723,23 @@ namespace UF
Mask const& GetChangesMask() const { return _changesMask; }
protected:
- template<typename T, int32 BlockBit, uint32 Bit>
- static void ClearChangesMask(UpdateField<T, BlockBit, Bit>& field)
+ template<typename T>
+ static inline void ClearChangesMask(UpdateFieldBase<T>& field)
{
if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
field._value.ClearChangesMask();
}
- template<typename T, std::size_t Size, uint32 Bit, int32 FirstElementBit>
- static void ClearChangesMask(UpdateFieldArray<T, Size, Bit, FirstElementBit>& field)
+ template<typename T, std::size_t Size>
+ static inline void ClearChangesMask(UpdateFieldArrayBase<T, Size>& field)
{
if constexpr (std::disjunction_v<std::is_base_of<HasChangesMaskTag, T>, std::is_base_of<IsUpdateFieldHolderTag, T>>)
for (T& value : field._values)
value.ClearChangesMask();
}
- template<typename T, int32 BlockBit, uint32 Bit>
- static void ClearChangesMask(DynamicUpdateField<T, BlockBit, Bit>& field)
+ template<typename T>
+ static inline void ClearChangesMask(DynamicUpdateFieldBase<T>& field)
{
if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
for (T& value : field._values)
@@ -653,16 +748,45 @@ namespace UF
field.ClearChangesMask();
}
- template<typename T, int32 BlockBit, uint32 Bit>
- static void ClearChangesMask(OptionalUpdateField<T, BlockBit, Bit>& field)
+ template<typename K, typename V>
+ static inline void ClearChangesMask(MapUpdateFieldBase<K, V>& field)
+ {
+ for (auto itr = field._values.begin(); itr != field._values.end(); )
+ {
+ switch (itr->second.state)
+ {
+ case MapUpdateFieldState::Unchanged:
+ break;
+ case MapUpdateFieldState::Changed:
+ if constexpr (std::is_base_of_v<HasChangesMaskTag, K>)
+ itr->first.ClearChangesMask();
+
+ if constexpr (std::is_base_of_v<HasChangesMaskTag, V>)
+ itr->second.value.ClearChangesMask();
+
+ itr->second.state = MapUpdateFieldState::Unchanged;
+ break;
+ case MapUpdateFieldState::Deleted:
+ itr = field._values.erase(itr++);
+ continue;
+ default:
+ break;
+ }
+
+ ++itr;
+ }
+ }
+
+ template<typename T>
+ static inline void ClearChangesMask(OptionalUpdateFieldBase<T>& field)
{
if constexpr (std::is_base_of_v<HasChangesMaskTag, T>)
if (field.has_value())
field._value->ClearChangesMask();
}
- template<int32 BlockBit, uint32 Bit, typename... Types>
- static void ClearChangesMask(VariantUpdateField<BlockBit, Bit, Types...>& field)
+ template<typename... Types>
+ static inline void ClearChangesMask(VariantUpdateFieldBase<Types...>& field)
{
if constexpr ((std::is_base_of_v<HasChangesMaskTag, Types> || ...))
std::visit([]<typename T>(T& value)
@@ -783,7 +907,6 @@ namespace UF
};
void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data, int32 bitsForSize = 32);
- void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data, int32 bitsForSize = 32);
template<typename T>
class DynamicUpdateFieldBase : public IsUpdateFieldHolderTag
@@ -887,6 +1010,81 @@ namespace UF
{
};
+ template<typename K, typename V>
+ class MapUpdateFieldBase : 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;
+
+ public:
+ struct Value
+ {
+ V value;
+ MapUpdateFieldState state;
+ };
+
+ using key_type = K;
+ using mapped_type = Value;
+ using value_type = std::pair<key_type const, mapped_type>;
+
+ typename std::unordered_map<K, Value>::const_iterator begin() const
+ {
+ return _values.begin();
+ }
+
+ typename std::unordered_map<K, Value>::const_iterator end() const
+ {
+ return _values.end();
+ }
+
+ bool empty() const
+ {
+ return _values.empty();
+ }
+
+ std::size_t size() const
+ {
+ return _values.size();
+ }
+
+ V const* Get(K const& key) const
+ {
+ auto itr = _values.find(key);
+ if (itr != _values.end())
+ return &itr->second.value;
+
+ return nullptr;
+ }
+
+ template <Trinity::invocable_r<bool, V const&> Pred>
+ std::pair<K const*, V const*> FindIf(Pred&& pred) const
+ {
+ auto itr = std::ranges::find_if(_values, std::forward<Pred>(pred),
+ [](value_type const& pair) -> V const& { return pair.second.value; });
+ if (itr != _values.end())
+ return std::make_pair(&itr->first, &itr->second.value);
+
+ return { nullptr, nullptr };
+ }
+
+ private:
+ std::unordered_map<K, Value> _values;
+ };
+
+ template<typename K, typename V, int32 BlockBit, uint32 Bit>
+ class MapUpdateField : public MapUpdateFieldBase<K, V>
+ {
+ };
+
template<typename T>
class OptionalUpdateFieldBase : public IsUpdateFieldHolderTag
{
diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldImpl.h b/src/server/game/Entities/Object/Updates/UpdateFieldImpl.h
new file mode 100644
index 00000000000..da0e68c3f3c
--- /dev/null
+++ b/src/server/game/Entities/Object/Updates/UpdateFieldImpl.h
@@ -0,0 +1,129 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITYCORE_UPDATE_FIELD_IMPL_H
+#define TRINITYCORE_UPDATE_FIELD_IMPL_H
+
+#include "UpdateField.h"
+#include "ByteBuffer.h"
+
+class Player;
+
+namespace UF
+{
+inline void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data, int32 bitsForSize /*= 32*/)
+{
+ data.WriteBits(size, bitsForSize);
+ if (size > 32)
+ {
+ if (data.HasUnfinishedBitPack())
+ for (std::size_t block = 0; block < size / 32; ++block)
+ data.WriteBits(updateMask[block], 32);
+ else
+ for (std::size_t block = 0; block < size / 32; ++block)
+ data << uint32(updateMask[block]);
+ }
+ else if (size == 32)
+ {
+ data.WriteBits(updateMask.back(), 32);
+ return;
+ }
+
+ if (size % 32)
+ data.WriteBits(updateMask.back(), size % 32);
+}
+
+inline void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data, int32 bitsForSize = 32)
+{
+ data.WriteBits(size, bitsForSize);
+ if (size > 32)
+ {
+ if (data.HasUnfinishedBitPack())
+ for (std::size_t block = 0; block < size / 32; ++block)
+ data.WriteBits(0xFFFFFFFFu, 32);
+ else
+ for (std::size_t block = 0; block < size / 32; ++block)
+ data << uint32(0xFFFFFFFFu);
+ }
+ else if (size == 32)
+ {
+ data.WriteBits(0xFFFFFFFFu, 32);
+ return;
+ }
+
+ if (size % 32)
+ data.WriteBits(0xFFFFFFFFu, size % 32);
+}
+
+template <typename K, typename V, typename T>
+inline void WriteMapFieldCreate(MapUpdateFieldBase<K, V> const& map, ByteBuffer& data, T const* owner, Player const* receiver)
+{
+ data << uint32(map.size());
+ for (auto const& [k, v] : map)
+ {
+ if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, K>)
+ k.WriteCreate(data, owner, receiver);
+ else
+ data << k;
+
+ if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, V>)
+ v.value.WriteCreate(data, owner, receiver);
+ else
+ data << v.value;
+ }
+}
+
+template <typename K, typename V, typename T>
+inline void WriteMapFieldUpdate(MapUpdateFieldBase<K, V> const& map, ByteBuffer& data, bool ignoreChangesMask, T const* owner, Player const* receiver)
+{
+ data << uint8(ignoreChangesMask ? 1 : 0);
+ if (ignoreChangesMask)
+ UF::WriteMapFieldCreate(map, data, owner, receiver);
+ else
+ {
+ uint16 changesCount = 0;
+ size_t changesCountPos = data.wpos();
+ data << uint16(changesCount);
+
+ for (auto const& [k, v] : map)
+ {
+ if (v.state == MapUpdateFieldState::Unchanged)
+ continue;
+
+ ++changesCount;
+
+ if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, K>)
+ k.WriteUpdate(data, true /*ignoreChangesMask*/, owner, receiver);
+ else
+ data << k;
+
+ data << uint8(v.state);
+ if (v.state == MapUpdateFieldState::Deleted)
+ continue;
+
+ if constexpr (std::is_base_of_v<IsUpdateFieldStructureTag, V>)
+ v.value.WriteUpdate(data, true /*ignoreChangesMask*/, owner, receiver); // client bug replaces unchanged values with 0/default so send everything as if it changed
+ else
+ data << v.value;
+ }
+
+ data.put<uint16>(changesCountPos, changesCount);
+ }
+}
+}
+
+#endif // TRINITYCORE_UPDATE_FIELD_IMPL_H
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
index 0db907a813a..7df3bcb97a5 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
@@ -22,6 +22,7 @@
#include "DynamicObject.h"
#include "PacketOperators.h"
#include "Player.h"
+#include "UpdateFieldImpl.h"
#include "ViewerDependentValues.h"
// This file is automatically generated, DO NOT EDIT
@@ -2098,14 +2099,14 @@ bool ChrCustomizationChoice::operator==(ChrCustomizationChoice const& right) con
void QuestLog::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
{
- data << int64(EndTime);
data << int32(QuestID);
- data << uint32(StateFlags);
- data << uint32(ObjectiveFlags);
+ data << uint16(StateFlags);
for (uint32 i = 0; i < 24; ++i)
{
data << int16(ObjectiveProgress[i]);
}
+ data << int64(EndTime);
+ data << uint32(ObjectiveFlags);
}
void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
@@ -2123,15 +2124,15 @@ void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player cons
{
if (changesMask[1])
{
- data << int64(EndTime);
+ data << int32(QuestID);
}
if (changesMask[2])
{
- data << int32(QuestID);
+ data << uint16(StateFlags);
}
if (changesMask[3])
{
- data << uint32(StateFlags);
+ data << int64(EndTime);
}
if (changesMask[4])
{
@@ -2152,9 +2153,9 @@ void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player cons
void QuestLog::ClearChangesMask()
{
- Base::ClearChangesMask(EndTime);
Base::ClearChangesMask(QuestID);
Base::ClearChangesMask(StateFlags);
+ Base::ClearChangesMask(EndTime);
Base::ClearChangesMask(ObjectiveFlags);
Base::ClearChangesMask(ObjectiveProgress);
_changesMask.ResetAll();
@@ -3508,8 +3509,8 @@ void CompletedProject::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Pla
void CompletedProject::ClearChangesMask()
{
- Base::ClearChangesMask(ProjectID);
Base::ClearChangesMask(FirstCompleted);
+ Base::ClearChangesMask(ProjectID);
Base::ClearChangesMask(CompletionCount);
_changesMask.ResetAll();
}
@@ -3809,6 +3810,7 @@ void TraitConfig::WriteCreate(ByteBuffer& data, Player const* owner, Player cons
if (Type == 3)
{
data << int32(TraitSystemID);
+ data << int32(VariationID);
}
for (uint32 i = 0; i < Entries.size(); ++i)
{
@@ -3829,7 +3831,7 @@ void TraitConfig::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player c
if (ignoreChangesMask)
changesMask.SetAll();
- data.WriteBits(changesMask.GetBlock(0), 14);
+ data.WriteBits(changesMask.GetBlock(0), 15);
if (changesMask[0])
{
@@ -3923,6 +3925,13 @@ void TraitConfig::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player c
data << int32(TraitSystemID);
}
}
+ if (changesMask[14])
+ {
+ if (Type == 3)
+ {
+ data << int32(VariationID);
+ }
+ }
}
if (changesMask[4])
{
@@ -3947,6 +3956,7 @@ void TraitConfig::ClearChangesMask()
Base::ClearChangesMask(CombatConfigFlags);
Base::ClearChangesMask(LocalIdentifier);
Base::ClearChangesMask(TraitSystemID);
+ Base::ClearChangesMask(VariationID);
_changesMask.ResetAll();
}
@@ -4822,6 +4832,7 @@ void ChallengeModeData::WriteCreate(ByteBuffer& data, Player const* owner, Playe
data << int64(Unknown_1120_4);
data << KeystoneOwnerGUID;
data << LeaverGUID;
+ data << int64(InstanceAbandonVoteCooldown);
data.WriteBits(IsActive, 1);
data.WriteBits(HasRestrictions, 1);
data.WriteBits(CanVoteAbandon, 1);
@@ -4836,6 +4847,7 @@ void ChallengeModeData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Pl
data << int64(Unknown_1120_4);
data << KeystoneOwnerGUID;
data << LeaverGUID;
+ data << int64(InstanceAbandonVoteCooldown);
data.WriteBits(IsActive, 1);
data.WriteBits(HasRestrictions, 1);
data.WriteBits(CanVoteAbandon, 1);
@@ -4850,6 +4862,7 @@ bool ChallengeModeData::operator==(ChallengeModeData const& right) const
&& Unknown_1120_4 == right.Unknown_1120_4
&& KeystoneOwnerGUID == right.KeystoneOwnerGUID
&& LeaverGUID == right.LeaverGUID
+ && InstanceAbandonVoteCooldown == right.InstanceAbandonVoteCooldown
&& IsActive == right.IsActive
&& HasRestrictions == right.HasRestrictions
&& CanVoteAbandon == right.CanVoteAbandon;
@@ -5038,7 +5051,6 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
data << int32(TransportServerTime);
data << uint32(WeeklyRewardsPeriodSinceOrigin);
data << int16(DEBUGSoulbindConduitRank);
- data << uint32(TraitConfigs.size());
data << uint32(ActiveCombatTraitConfigID);
data << uint32(CraftingOrders.size());
data << uint32(PersonalCraftingOrderCounts.size());
@@ -5196,6 +5208,7 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
data << *FrozenPerksVendorItem;
Field_1410->WriteCreate(data, owner, receiver);
data << *DungeonScore;
+ WriteMapFieldCreate(TraitConfigs, data, owner, receiver);
for (uint32 i = 0; i < PvpInfo.size(); ++i)
{
PvpInfo[i].WriteCreate(data, owner, receiver);
@@ -5204,10 +5217,6 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
{
CharacterRestrictions[i].WriteCreate(data, owner, receiver);
}
- for (uint32 i = 0; i < TraitConfigs.size(); ++i)
- {
- TraitConfigs[i].WriteCreate(data, owner, receiver);
- }
for (uint32 i = 0; i < CraftingOrders.size(); ++i)
{
CraftingOrders[i].WriteCreate(data, owner, receiver);
@@ -5306,11 +5315,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data);
}
}
- if (changesMask[43])
+ if (changesMask[42])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[44])
+ if (changesMask[43])
{
if (!ignoreNestedChangesMask)
ResearchSites[i].WriteUpdateMask(data);
@@ -5319,11 +5328,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[45])
+ if (changesMask[44])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[46])
+ if (changesMask[45])
{
if (!ignoreNestedChangesMask)
ResearchSiteProgress[i].WriteUpdateMask(data);
@@ -5332,11 +5341,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[47])
+ if (changesMask[46])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[48])
+ if (changesMask[47])
{
if (!ignoreNestedChangesMask)
Research[i].WriteUpdateMask(data);
@@ -5345,11 +5354,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[43])
+ if (changesMask[42])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[44])
+ if (changesMask[43])
{
for (uint32 j = 0; j < ResearchSites[i].size(); ++j)
{
@@ -5361,11 +5370,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[45])
+ if (changesMask[44])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[46])
+ if (changesMask[45])
{
for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j)
{
@@ -5377,11 +5386,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[47])
+ if (changesMask[46])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[48])
+ if (changesMask[47])
{
for (uint32 j = 0; j < Research[i].size(); ++j)
{
@@ -5556,46 +5565,39 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
if (changesMask[34])
{
if (!ignoreNestedChangesMask)
- TraitConfigs.WriteUpdateMask(data);
- else
- WriteCompleteDynamicFieldUpdateMask(TraitConfigs.size(), data);
- }
- if (changesMask[35])
- {
- if (!ignoreNestedChangesMask)
CraftingOrders.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data);
}
- if (changesMask[36])
+ if (changesMask[35])
{
if (!ignoreNestedChangesMask)
PersonalCraftingOrderCounts.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(PersonalCraftingOrderCounts.size(), data);
}
- if (changesMask[37])
+ if (changesMask[36])
{
if (!ignoreNestedChangesMask)
NpcCraftingOrders.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(NpcCraftingOrders.size(), data);
}
- if (changesMask[38])
+ if (changesMask[37])
{
if (!ignoreNestedChangesMask)
CategoryCooldownMods.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data);
}
- if (changesMask[39])
+ if (changesMask[38])
{
if (!ignoreNestedChangesMask)
WeeklySpellUses.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data);
}
- if (changesMask[40])
+ if (changesMask[39])
{
if (!ignoreNestedChangesMask)
TrackedCollectableSources.WriteUpdateMask(data);
@@ -5849,7 +5851,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[36])
+ if (changesMask[35])
{
for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i)
{
@@ -5859,7 +5861,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[37])
+ if (changesMask[36])
{
for (uint32 i = 0; i < NpcCraftingOrders.size(); ++i)
{
@@ -5869,7 +5871,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[38])
+ if (changesMask[37])
{
for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i)
{
@@ -5879,7 +5881,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[39])
+ if (changesMask[38])
{
for (uint32 i = 0; i < WeeklySpellUses.size(); ++i)
{
@@ -5889,7 +5891,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[40])
+ if (changesMask[39])
{
for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i)
{
@@ -5903,14 +5905,14 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
data.FlushBits();
if (changesMask[32])
{
- if (changesMask[41])
+ if (changesMask[40])
{
if (!ignoreNestedChangesMask)
CharacterBankTabSettings.WriteUpdateMask(data, 3);
else
WriteCompleteDynamicFieldUpdateMask(CharacterBankTabSettings.size(), data, 3);
}
- if (changesMask[42])
+ if (changesMask[41])
{
if (!ignoreNestedChangesMask)
AccountBankTabSettings.WriteUpdateMask(data, 3);
@@ -5946,16 +5948,6 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
{
if (changesMask[34])
{
- for (uint32 i = 0; i < TraitConfigs.size(); ++i)
- {
- if (TraitConfigs.HasChanged(i) || ignoreNestedChangesMask)
- {
- TraitConfigs[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
- }
- }
- }
- if (changesMask[35])
- {
for (uint32 i = 0; i < CraftingOrders.size(); ++i)
{
if (CraftingOrders.HasChanged(i) || ignoreNestedChangesMask)
@@ -5964,7 +5956,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[41])
+ if (changesMask[40])
{
for (uint32 i = 0; i < CharacterBankTabSettings.size(); ++i)
{
@@ -5974,7 +5966,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[42])
+ if (changesMask[41])
{
for (uint32 i = 0; i < AccountBankTabSettings.size(); ++i)
{
@@ -5984,337 +5976,337 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[49])
+ if (changesMask[48])
{
data << *FarsightObject;
}
- if (changesMask[50])
+ if (changesMask[49])
{
data << *SummonedBattlePetGUID;
}
- if (changesMask[51])
+ if (changesMask[50])
{
data << uint64(Coinage);
}
- if (changesMask[52])
+ if (changesMask[51])
{
data << uint64(AccountBankCoinage);
}
- if (changesMask[53])
+ if (changesMask[52])
{
data << int32(XP);
}
- if (changesMask[54])
+ if (changesMask[53])
{
data << int32(NextLevelXP);
}
- if (changesMask[55])
+ if (changesMask[54])
{
data << int32(TrialXP);
}
- if (changesMask[56])
+ if (changesMask[55])
{
Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
- if (changesMask[57])
+ if (changesMask[56])
{
data << int32(CharacterPoints);
}
- if (changesMask[58])
+ if (changesMask[57])
{
data << int32(MaxTalentTiers);
}
- if (changesMask[59])
+ if (changesMask[58])
{
data << uint32(TrackCreatureMask);
}
- if (changesMask[60])
+ if (changesMask[59])
{
data << float(MainhandExpertise);
}
- if (changesMask[61])
+ if (changesMask[60])
{
data << float(OffhandExpertise);
}
- if (changesMask[62])
+ if (changesMask[61])
{
data << float(RangedExpertise);
}
- if (changesMask[63])
+ if (changesMask[62])
{
data << float(CombatRatingExpertise);
}
- if (changesMask[64])
+ if (changesMask[63])
{
data << float(BlockPercentage);
}
- if (changesMask[65])
+ if (changesMask[64])
{
data << float(DodgePercentage);
}
- if (changesMask[66])
+ if (changesMask[65])
{
data << float(DodgePercentageFromAttribute);
}
- if (changesMask[67])
+ if (changesMask[66])
{
data << float(ParryPercentage);
}
- if (changesMask[68])
+ if (changesMask[67])
{
data << float(ParryPercentageFromAttribute);
}
- if (changesMask[69])
+ if (changesMask[68])
{
data << float(CritPercentage);
}
+ if (changesMask[69])
+ {
+ data << float(RangedCritPercentage);
+ }
}
if (changesMask[70])
{
if (changesMask[71])
{
- data << float(RangedCritPercentage);
+ data << float(OffhandCritPercentage);
}
if (changesMask[72])
{
- data << float(OffhandCritPercentage);
+ data << float(SpellCritPercentage);
}
if (changesMask[73])
{
- data << float(SpellCritPercentage);
+ data << int32(ShieldBlock);
}
if (changesMask[74])
{
- data << int32(ShieldBlock);
+ data << float(ShieldBlockCritPercentage);
}
if (changesMask[75])
{
- data << float(ShieldBlockCritPercentage);
+ data << float(Mastery);
}
if (changesMask[76])
{
- data << float(Mastery);
+ data << float(Speed);
}
if (changesMask[77])
{
- data << float(Speed);
+ data << float(Avoidance);
}
if (changesMask[78])
{
- data << float(Avoidance);
+ data << float(Sturdiness);
}
if (changesMask[79])
{
- data << float(Sturdiness);
+ data << int32(Versatility);
}
if (changesMask[80])
{
- data << int32(Versatility);
+ data << float(VersatilityBonus);
}
if (changesMask[81])
{
- data << float(VersatilityBonus);
+ data << float(PvpPowerDamage);
}
if (changesMask[82])
{
- data << float(PvpPowerDamage);
+ data << float(PvpPowerHealing);
}
if (changesMask[83])
{
- data << float(PvpPowerHealing);
+ BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
if (changesMask[84])
{
- BitVectors->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ data << int32(ModHealingDonePos);
}
if (changesMask[85])
{
- data << int32(ModHealingDonePos);
+ data << float(ModHealingPercent);
}
if (changesMask[86])
{
- data << float(ModHealingPercent);
+ data << float(ModPeriodicHealingDonePercent);
}
if (changesMask[87])
{
- data << float(ModPeriodicHealingDonePercent);
+ data << float(ModSpellPowerPercent);
}
if (changesMask[88])
{
- data << float(ModSpellPowerPercent);
+ data << float(ModResiliencePercent);
}
if (changesMask[89])
{
- data << float(ModResiliencePercent);
+ data << float(OverrideSpellPowerByAPPercent);
}
if (changesMask[90])
{
- data << float(OverrideSpellPowerByAPPercent);
+ data << float(OverrideAPBySpellPowerPercent);
}
if (changesMask[91])
{
- data << float(OverrideAPBySpellPowerPercent);
+ data << int32(ModTargetResistance);
}
if (changesMask[92])
{
- data << int32(ModTargetResistance);
+ data << int32(ModTargetPhysicalResistance);
}
if (changesMask[93])
{
- data << int32(ModTargetPhysicalResistance);
+ data << uint32(LocalFlags);
}
if (changesMask[94])
{
- data << uint32(LocalFlags);
+ data << uint8(GrantableLevels);
}
if (changesMask[95])
{
- data << uint8(GrantableLevels);
+ data << uint8(MultiActionBars);
}
if (changesMask[96])
{
- data << uint8(MultiActionBars);
+ data << uint8(LifetimeMaxRank);
}
if (changesMask[97])
{
- data << uint8(LifetimeMaxRank);
+ data << uint8(NumRespecs);
}
if (changesMask[98])
{
- data << uint8(NumRespecs);
+ data << uint32(PvpMedals);
}
if (changesMask[99])
{
- data << uint32(PvpMedals);
+ data << uint16(TodayHonorableKills);
}
if (changesMask[100])
{
- data << uint16(TodayHonorableKills);
+ data << uint16(YesterdayHonorableKills);
}
if (changesMask[101])
{
- data << uint16(YesterdayHonorableKills);
+ data << uint32(LifetimeHonorableKills);
}
}
if (changesMask[102])
{
if (changesMask[103])
{
- data << uint32(LifetimeHonorableKills);
+ data << int32(WatchedFactionIndex);
}
if (changesMask[104])
{
- data << int32(WatchedFactionIndex);
+ data << int32(MaxLevel);
}
if (changesMask[105])
{
- data << int32(MaxLevel);
+ data << int32(ScalingPlayerLevelDelta);
}
if (changesMask[106])
{
- data << int32(ScalingPlayerLevelDelta);
+ data << int32(MaxCreatureScalingLevel);
}
if (changesMask[107])
{
- data << int32(MaxCreatureScalingLevel);
+ data << int32(PetSpellPower);
}
if (changesMask[108])
{
- data << int32(PetSpellPower);
+ data << float(UiHitModifier);
}
if (changesMask[109])
{
- data << float(UiHitModifier);
+ data << float(UiSpellHitModifier);
}
if (changesMask[110])
{
- data << float(UiSpellHitModifier);
+ data << int32(HomeRealmTimeOffset);
}
if (changesMask[111])
{
- data << int32(HomeRealmTimeOffset);
+ data << float(ModPetHaste);
}
if (changesMask[112])
{
- data << float(ModPetHaste);
+ data << int8(JailersTowerLevelMax);
}
if (changesMask[113])
{
- data << int8(JailersTowerLevelMax);
+ data << int8(JailersTowerLevel);
}
if (changesMask[114])
{
- data << int8(JailersTowerLevel);
+ data << uint8(LocalRegenFlags);
}
if (changesMask[115])
{
- data << uint8(LocalRegenFlags);
+ data << uint8(AuraVision);
}
if (changesMask[116])
{
- data << uint8(AuraVision);
+ data << uint8(NumBackpackSlots);
}
if (changesMask[117])
{
- data << uint8(NumBackpackSlots);
+ data << int32(OverrideSpellsID);
}
if (changesMask[118])
{
- data << int32(OverrideSpellsID);
+ data << uint16(LootSpecID);
}
if (changesMask[119])
{
- data << uint16(LootSpecID);
+ data << uint32(OverrideZonePVPType);
}
if (changesMask[120])
{
- data << uint32(OverrideZonePVPType);
+ data << int32(Honor);
}
if (changesMask[121])
{
- data << int32(Honor);
+ data << int32(HonorNextLevel);
}
if (changesMask[122])
{
- data << int32(HonorNextLevel);
+ data << int32(PerksProgramCurrency);
}
if (changesMask[123])
{
- data << int32(PerksProgramCurrency);
+ data << uint8(NumBankSlots);
}
if (changesMask[124])
{
- data << uint8(NumBankSlots);
+ data << uint8(NumCharacterBankTabs);
}
if (changesMask[125])
{
- data << uint8(NumCharacterBankTabs);
+ data << uint8(NumAccountBankTabs);
}
- if (changesMask[126])
+ if (changesMask[130])
{
- data << uint8(NumAccountBankTabs);
+ data << int32(UiChromieTimeExpansionID);
}
if (changesMask[131])
{
- data << int32(UiChromieTimeExpansionID);
+ data << int32(TimerunningSeasonID);
}
if (changesMask[132])
{
- data << int32(TimerunningSeasonID);
+ data << int32(TransportServerTime);
}
if (changesMask[133])
{
- data << int32(TransportServerTime);
+ data << uint32(WeeklyRewardsPeriodSinceOrigin);
}
}
if (changesMask[134])
{
if (changesMask[135])
{
- data << uint32(WeeklyRewardsPeriodSinceOrigin);
- }
- if (changesMask[136])
- {
data << int16(DEBUGSoulbindConduitRank);
}
if (changesMask[138])
@@ -6364,32 +6356,36 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
data.FlushBits();
if (changesMask[102])
{
- if (changesMask[127])
+ if (changesMask[126])
{
ResearchHistory->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
- if (changesMask[129])
+ if (changesMask[128])
{
if (QuestSession.has_value())
{
QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
}
- if (changesMask[128])
+ if (changesMask[127])
{
data << *FrozenPerksVendorItem;
}
- if (changesMask[130])
+ if (changesMask[129])
{
Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
}
if (changesMask[134])
{
- if (changesMask[137])
+ if (changesMask[136])
{
data << *DungeonScore;
}
+ if (changesMask[137])
+ {
+ WriteMapFieldUpdate(TraitConfigs, data, ignoreNestedChangesMask, owner, receiver);
+ }
if (changesMask[145])
{
if (PetStable.has_value())
@@ -6584,7 +6580,6 @@ void ActivePlayerData::ClearChangesMask()
Base::ClearChangesMask(TrackedCollectableSources);
Base::ClearChangesMask(PvpInfo);
Base::ClearChangesMask(CharacterRestrictions);
- Base::ClearChangesMask(TraitConfigs);
Base::ClearChangesMask(CraftingOrders);
Base::ClearChangesMask(CharacterBankTabSettings);
Base::ClearChangesMask(AccountBankTabSettings);
@@ -6674,6 +6669,7 @@ void ActivePlayerData::ClearChangesMask()
Base::ClearChangesMask(WeeklyRewardsPeriodSinceOrigin);
Base::ClearChangesMask(DEBUGSoulbindConduitRank);
Base::ClearChangesMask(DungeonScore);
+ Base::ClearChangesMask(TraitConfigs);
Base::ClearChangesMask(ActiveCombatTraitConfigID);
Base::ClearChangesMask(ItemUpgradeHighOnehandWeaponItemID);
Base::ClearChangesMask(ItemUpgradeHighFingerItemID);
@@ -7240,10 +7236,15 @@ void ScaleCurve::ClearChangesMask()
void VisualAnim::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const
{
- data << uint32(AnimationDataID);
+ data.WriteBits(AnimationDataID.has_value(), 1);
+ data.WriteBit(IsDecay);
+ data.FlushBits();
data << uint32(AnimKitID);
data << uint32(AnimProgress);
- data.WriteBit(IsDecay);
+ if (AnimationDataID.has_value())
+ {
+ data << int16(AnimationDataID);
+ }
data.FlushBits();
}
@@ -7261,14 +7262,11 @@ void VisualAnim::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigg
{
data.WriteBit(IsDecay);
}
+ data.WriteBits(AnimationDataID.has_value(), 1);
}
data.FlushBits();
if (changesMask[0])
{
- if (changesMask[2])
- {
- data << uint32(AnimationDataID);
- }
if (changesMask[3])
{
data << uint32(AnimKitID);
@@ -7277,6 +7275,13 @@ void VisualAnim::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigg
{
data << uint32(AnimProgress);
}
+ if (changesMask[2])
+ {
+ if (AnimationDataID.has_value())
+ {
+ data << int16(AnimationDataID);
+ }
+ }
}
data.FlushBits();
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index b4acb53e749..aad04046fb0 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -455,9 +455,9 @@ struct ChrCustomizationChoice : public IsUpdateFieldStructureTag
struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<30>
{
- UpdateField<int64, 0, 1> EndTime;
- UpdateField<int32, 0, 2> QuestID;
- UpdateField<uint32, 0, 3> StateFlags;
+ UpdateField<int32, 0, 1> QuestID;
+ UpdateField<uint16, 0, 2> StateFlags;
+ UpdateField<int64, 0, 3> EndTime;
UpdateField<uint32, 0, 4> ObjectiveFlags;
UpdateFieldArray<int16, 24, 5, 6> ObjectiveProgress;
@@ -846,7 +846,7 @@ struct TraitSubTreeCache : public IsUpdateFieldStructureTag
bool operator!=(TraitSubTreeCache const& right) const { return !(*this == right); }
};
-struct TraitConfig : public IsUpdateFieldStructureTag, public HasChangesMask<14>
+struct TraitConfig : public IsUpdateFieldStructureTag, public HasChangesMask<15>
{
DynamicUpdateField<UF::TraitEntry, 0, 1> Entries;
DynamicUpdateField<UF::TraitSubTreeCache, 0, 2> SubTrees;
@@ -858,6 +858,7 @@ struct TraitConfig : public IsUpdateFieldStructureTag, public HasChangesMask<14>
UpdateField<int32, 8, 10> CombatConfigFlags;
UpdateField<int32, 8, 11> LocalIdentifier;
UpdateField<int32, 12, 13> TraitSystemID;
+ UpdateField<int32, 12, 14> VariationID;
void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
@@ -1069,6 +1070,7 @@ struct ChallengeModeData : public IsUpdateFieldStructureTag
int64 Unknown_1120_4;
ObjectGuid KeystoneOwnerGUID;
ObjectGuid LeaverGUID;
+ int64 InstanceAbandonVoteCooldown;
uint32 IsActive;
uint32 HasRestrictions;
uint32 CanVoteAbandon;
@@ -1097,9 +1099,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, 43, 44> ResearchSites;
- UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 45, 46> ResearchSiteProgress;
- UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 47, 48> Research;
+ UpdateFieldArray<DynamicUpdateFieldBase<uint16>, 1, 42, 43> ResearchSites;
+ UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 44, 45> ResearchSiteProgress;
+ UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 46, 47> Research;
DynamicUpdateField<uint64, 0, 7> KnownTitles;
DynamicUpdateField<UF::PlayerDataElement, 0, 8> CharacterDataElements;
DynamicUpdateField<UF::PlayerDataElement, 0, 9> AccountDataElements;
@@ -1124,103 +1126,103 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas
DynamicUpdateField<UF::ReplayedQuest, 0, 30> ReplayedQuests;
DynamicUpdateField<UF::QuestLog, 0, 31> TaskQuests;
DynamicUpdateField<int32, 32, 33> DisabledSpells;
- DynamicUpdateField<UF::PersonalCraftingOrderCount, 32, 36> PersonalCraftingOrderCounts;
- DynamicUpdateField<UF::NPCCraftingOrderInfo, 32, 37> NpcCraftingOrders;
- DynamicUpdateField<UF::CategoryCooldownMod, 32, 38> CategoryCooldownMods;
- DynamicUpdateField<UF::WeeklySpellUse, 32, 39> WeeklySpellUses;
- DynamicUpdateField<UF::CollectableSourceTrackedData, 32, 40> TrackedCollectableSources;
+ DynamicUpdateField<UF::PersonalCraftingOrderCount, 32, 35> PersonalCraftingOrderCounts;
+ DynamicUpdateField<UF::NPCCraftingOrderInfo, 32, 36> NpcCraftingOrders;
+ DynamicUpdateField<UF::CategoryCooldownMod, 32, 37> CategoryCooldownMods;
+ DynamicUpdateField<UF::WeeklySpellUse, 32, 38> WeeklySpellUses;
+ DynamicUpdateField<UF::CollectableSourceTrackedData, 32, 39> TrackedCollectableSources;
DynamicUpdateField<UF::PVPInfo, 0, 10> PvpInfo;
DynamicUpdateField<UF::CharacterRestriction, 0, 24> CharacterRestrictions;
- DynamicUpdateField<UF::TraitConfig, 32, 34> TraitConfigs;
- DynamicUpdateField<UF::CraftingOrder, 32, 35> CraftingOrders;
- 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;
+ DynamicUpdateField<UF::CraftingOrder, 32, 34> CraftingOrders;
+ DynamicUpdateField<UF::BankTabSettings, 32, 40> CharacterBankTabSettings;
+ DynamicUpdateField<UF::BankTabSettings, 32, 41> AccountBankTabSettings;
+ UpdateField<ObjectGuid, 32, 48> FarsightObject;
+ UpdateField<ObjectGuid, 32, 49> SummonedBattlePetGUID;
+ UpdateField<uint64, 32, 50> Coinage;
+ UpdateField<uint64, 32, 51> AccountBankCoinage;
+ UpdateField<int32, 32, 52> XP;
+ UpdateField<int32, 32, 53> NextLevelXP;
+ UpdateField<int32, 32, 54> TrialXP;
+ UpdateField<UF::SkillInfo, 32, 55> Skill;
+ UpdateField<int32, 32, 56> CharacterPoints;
+ UpdateField<int32, 32, 57> MaxTalentTiers;
+ UpdateField<uint32, 32, 58> TrackCreatureMask;
+ UpdateField<float, 32, 59> MainhandExpertise;
+ UpdateField<float, 32, 60> OffhandExpertise;
+ UpdateField<float, 32, 61> RangedExpertise;
+ UpdateField<float, 32, 62> CombatRatingExpertise;
+ UpdateField<float, 32, 63> BlockPercentage;
+ UpdateField<float, 32, 64> DodgePercentage;
+ UpdateField<float, 32, 65> DodgePercentageFromAttribute;
+ UpdateField<float, 32, 66> ParryPercentage;
+ UpdateField<float, 32, 67> ParryPercentageFromAttribute;
+ UpdateField<float, 32, 68> CritPercentage;
+ UpdateField<float, 32, 69> RangedCritPercentage;
+ UpdateField<float, 70, 71> OffhandCritPercentage;
+ UpdateField<float, 70, 72> SpellCritPercentage;
+ UpdateField<int32, 70, 73> ShieldBlock;
+ UpdateField<float, 70, 74> ShieldBlockCritPercentage;
+ UpdateField<float, 70, 75> Mastery;
+ UpdateField<float, 70, 76> Speed;
+ UpdateField<float, 70, 77> Avoidance;
+ UpdateField<float, 70, 78> Sturdiness;
+ UpdateField<int32, 70, 79> Versatility;
+ UpdateField<float, 70, 80> VersatilityBonus;
+ UpdateField<float, 70, 81> PvpPowerDamage;
+ UpdateField<float, 70, 82> PvpPowerHealing;
+ UpdateField<UF::BitVectors, 70, 83> BitVectors;
+ UpdateField<int32, 70, 84> ModHealingDonePos;
+ UpdateField<float, 70, 85> ModHealingPercent;
+ UpdateField<float, 70, 86> ModPeriodicHealingDonePercent;
+ UpdateField<float, 70, 87> ModSpellPowerPercent;
+ UpdateField<float, 70, 88> ModResiliencePercent;
+ UpdateField<float, 70, 89> OverrideSpellPowerByAPPercent;
+ UpdateField<float, 70, 90> OverrideAPBySpellPowerPercent;
+ UpdateField<int32, 70, 91> ModTargetResistance;
+ UpdateField<int32, 70, 92> ModTargetPhysicalResistance;
+ UpdateField<uint32, 70, 93> LocalFlags;
+ UpdateField<uint8, 70, 94> GrantableLevels;
+ UpdateField<uint8, 70, 95> MultiActionBars;
+ UpdateField<uint8, 70, 96> LifetimeMaxRank;
+ UpdateField<uint8, 70, 97> NumRespecs;
+ UpdateField<uint32, 70, 98> PvpMedals;
+ UpdateField<uint16, 70, 99> TodayHonorableKills;
+ UpdateField<uint16, 70, 100> YesterdayHonorableKills;
+ UpdateField<uint32, 70, 101> LifetimeHonorableKills;
+ UpdateField<int32, 102, 103> WatchedFactionIndex;
+ UpdateField<int32, 102, 104> MaxLevel;
+ UpdateField<int32, 102, 105> ScalingPlayerLevelDelta;
+ UpdateField<int32, 102, 106> MaxCreatureScalingLevel;
+ UpdateField<int32, 102, 107> PetSpellPower;
+ UpdateField<float, 102, 108> UiHitModifier;
+ UpdateField<float, 102, 109> UiSpellHitModifier;
+ UpdateField<int32, 102, 110> HomeRealmTimeOffset;
+ UpdateField<float, 102, 111> ModPetHaste;
+ UpdateField<int8, 102, 112> JailersTowerLevelMax;
+ UpdateField<int8, 102, 113> JailersTowerLevel;
+ UpdateField<uint8, 102, 114> LocalRegenFlags;
+ UpdateField<uint8, 102, 115> AuraVision;
+ UpdateField<uint8, 102, 116> NumBackpackSlots;
+ UpdateField<int32, 102, 117> OverrideSpellsID;
+ UpdateField<uint16, 102, 118> LootSpecID;
+ UpdateField<uint32, 102, 119> OverrideZonePVPType;
+ UpdateField<int32, 102, 120> Honor;
+ UpdateField<int32, 102, 121> HonorNextLevel;
+ UpdateField<int32, 102, 122> PerksProgramCurrency;
+ UpdateField<uint8, 102, 123> NumBankSlots;
+ UpdateField<uint8, 102, 124> NumCharacterBankTabs;
+ UpdateField<uint8, 102, 125> NumAccountBankTabs;
+ UpdateField<UF::ResearchHistory, 102, 126> ResearchHistory;
+ UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 102, 127> FrozenPerksVendorItem;
+ UpdateField<UF::ActivePlayerUnk901, 102, 129> Field_1410;
+ OptionalUpdateField<UF::QuestSession, 102, 128> QuestSession;
+ UpdateField<int32, 102, 130> UiChromieTimeExpansionID;
+ UpdateField<int32, 102, 131> TimerunningSeasonID;
+ UpdateField<int32, 102, 132> TransportServerTime;
+ UpdateField<uint32, 102, 133> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin
+ UpdateField<int16, 134, 135> DEBUGSoulbindConduitRank;
+ UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 134, 136> DungeonScore;
+ MapUpdateField<int32, UF::TraitConfig, 134, 137> TraitConfigs;
UpdateField<uint32, 134, 138> ActiveCombatTraitConfigID;
UpdateField<int32, 134, 139> ItemUpgradeHighOnehandWeaponItemID;
UpdateField<int32, 134, 140> ItemUpgradeHighFingerItemID;
@@ -1363,7 +1365,7 @@ struct ScaleCurve : public IsUpdateFieldStructureTag, public HasChangesMask<7>
struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5>
{
UpdateField<bool, 0, 1> IsDecay;
- UpdateField<uint32, 0, 2> AnimationDataID;
+ OptionalUpdateField<int16, 0, 2> AnimationDataID;
UpdateField<uint32, 0, 3> AnimKitID;
UpdateField<uint32, 0, 4> AnimProgress;
diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h
index 4ccb7af8fbb..3071632d603 100644
--- a/src/server/game/Entities/Object/Updates/UpdateMask.h
+++ b/src/server/game/Entities/Object/Updates/UpdateMask.h
@@ -97,15 +97,15 @@ public:
constexpr void SetAll()
{
std::memset(_blocksMask.data(), 0xFF, _blocksMask.size() * sizeof(typename decltype(_blocksMask)::value_type));
- if constexpr (BlocksMaskCount % 32)
+ if constexpr (BlockCount % 32)
{
- constexpr uint32 unused = 32 - (BlocksMaskCount % 32);
+ constexpr uint32 unused = 32 - (BlockCount % 32);
_blocksMask.back() &= (0xFFFFFFFF >> unused);
}
std::memset(_blocks.data(), 0xFF, _blocks.size() * sizeof(typename decltype(_blocks)::value_type));
- if constexpr (BlockCount % 32)
+ if constexpr (Bits % 32)
{
- constexpr uint32 unused = 32 - (BlockCount % 32);
+ constexpr uint32 unused = 32 - (Bits % 32);
_blocks.back() &= (0xFFFFFFFF >> unused);
}
}