diff options
author | Shauren <shauren.trinity@gmail.com> | 2016-07-13 00:07:09 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-07-13 00:07:09 +0200 |
commit | db85bad1ff349d2e710de34d2a3dd8ae2a2a07a8 (patch) | |
tree | c21828ed101facb8727f1f35ad9a7933c09019b0 | |
parent | cb803e58ffc4cbd953a47b3e642daa0cd552ffbe (diff) |
Core/PacketIO: Fixed dynamic updatefield handling when values get removed
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 13 |
3 files changed, 30 insertions, 7 deletions
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index cbcf2bb2a77..83c62eb005f 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1145,7 +1145,10 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player* UpdateMask::SetUpdateBit(data->contents() + maskPos, index); std::size_t arrayBlockCount = UpdateMask::GetBlockCount(values.size()); - *data << uint8(arrayBlockCount); + *data << uint8(UpdateMask::EncodeDynamicFieldChangeType(arrayBlockCount, _dynamicChangesMask[index], updateType)); + if (_dynamicChangesMask[index] == UpdateMask::VALUE_AND_SIZE_CHANGED && updateType == UPDATETYPE_VALUES) + *data << uint16(values.size()); + std::size_t arrayMaskPos = data->wpos(); data->resize(data->size() + arrayBlockCount * sizeof(UpdateMask::BlockType)); if (index != ITEM_DYNAMIC_FIELD_MODIFIERS) @@ -1158,13 +1161,13 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player* *data << uint32(values[v]); } } - } else { // in case of ITEM_DYNAMIC_FIELD_MODIFIERS it is ITEM_FIELD_MODIFIERS_MASK that controls index of each value, not updatemask // so we just have to write this starting from 0 index - for (std::size_t v = 0, m = 0; v < values.size(); ++v) + uint16 m = 0; + for (std::size_t v = 0; v < values.size(); ++v) { if (values[v]) { @@ -1173,6 +1176,8 @@ void Item::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player* } } + if (_changesMask[ITEM_FIELD_MODIFIERS_MASK] && updateType == UPDATETYPE_VALUES) + data->put(arrayMaskPos - sizeof(m), m); } } } diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index cce819c1dc2..9f3b50c3d62 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -793,7 +793,10 @@ void Object::BuildDynamicValuesUpdate(uint8 updateType, ByteBuffer* data, Player UpdateMask::SetUpdateBit(data->contents() + maskPos, index); std::size_t arrayBlockCount = UpdateMask::GetBlockCount(values.size()); - *data << uint8(arrayBlockCount); + *data << uint8(UpdateMask::EncodeDynamicFieldChangeType(arrayBlockCount, _dynamicChangesMask[index], updateType)); + if (_dynamicChangesMask[index] == UpdateMask::VALUE_AND_SIZE_CHANGED && updateType == UPDATETYPE_VALUES) + *data << uint16(values.size()); + std::size_t arrayMaskPos = data->wpos(); data->resize(data->size() + arrayBlockCount * sizeof(UpdateMask::BlockType)); for (std::size_t v = 0; v < values.size(); ++v) @@ -1359,7 +1362,7 @@ void Object::ClearDynamicValue(uint16 index) if (!_dynamicValues[index].empty()) { _dynamicValues[index].clear(); - _dynamicChangesMask[index] = 1; + _dynamicChangesMask[index] = UpdateMask::VALUE_AND_SIZE_CHANGED; _dynamicChangesArrayMask[index].clear(); AddToObjectUpdateIfNeeded(); @@ -1370,9 +1373,13 @@ void Object::SetDynamicValue(uint16 index, uint8 offset, uint32 value) { ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false)); + UpdateMask::DynamicFieldChangeType changeType = UpdateMask::VALUE_CHANGED; std::vector<uint32>& values = _dynamicValues[index]; if (values.size() <= offset) + { values.resize(offset + 1); + changeType = UpdateMask::VALUE_AND_SIZE_CHANGED; + } if (_dynamicChangesArrayMask[index].size() <= offset) _dynamicChangesArrayMask[index].resize((offset / 32 + 1) * 32); @@ -1380,7 +1387,7 @@ void Object::SetDynamicValue(uint16 index, uint8 offset, uint32 value) if (values[offset] != value) { values[offset] = value; - _dynamicChangesMask[index] = 1; + _dynamicChangesMask[index] = changeType; _dynamicChangesArrayMask[index][offset] = 1; AddToObjectUpdateIfNeeded(); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 25bddef1535..d41e34dcac3 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -96,12 +96,23 @@ namespace UpdateMask { typedef uint32 BlockType; + enum DynamicFieldChangeType : uint8 + { + VALUE_CHANGED = 0x7F, + VALUE_AND_SIZE_CHANGED = 0x80 + }; + inline std::size_t GetBlockCount(std::size_t bitCount) { using BitsPerBlock = std::integral_constant<std::size_t, sizeof(BlockType) * 8>; return (bitCount + BitsPerBlock::value - 1) / BitsPerBlock::value; } + inline std::size_t EncodeDynamicFieldChangeType(std::size_t blockCount, DynamicFieldChangeType changeType, uint8 updateType) + { + return blockCount | ((changeType & VALUE_AND_SIZE_CHANGED) * (3 - updateType /*this part evaluates to 0 if update type is not VALUES*/)); + } + template<typename T> inline void SetUpdateBit(T* data, std::size_t bitIndex) { @@ -259,7 +270,7 @@ class TC_GAME_API Object std::vector<uint32>* _dynamicValues; std::vector<uint8> _changesMask; - std::vector<uint8> _dynamicChangesMask; + std::vector<UpdateMask::DynamicFieldChangeType> _dynamicChangesMask; std::vector<uint8>* _dynamicChangesArrayMask; uint16 m_valuesCount; |