diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-10-10 16:21:55 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-10-10 16:21:55 +0200 |
| commit | 53068a94e88991ae7196fb247df4b7ca2e47e554 (patch) | |
| tree | 42afe6e6160b0317f72ddec25562988145d7a5ff /src/server/game/Entities/Object | |
| parent | a7d825c6deb2711392956abac2d494a8731f58c3 (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.h | 13 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateField.cpp | 63 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateField.h | 224 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFieldImpl.h | 129 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.cpp | 311 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 208 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateMask.h | 8 |
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); } } |
