aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-07-13 00:07:09 +0200
committerShauren <shauren.trinity@gmail.com>2016-07-13 00:07:09 +0200
commitdb85bad1ff349d2e710de34d2a3dd8ae2a2a07a8 (patch)
treec21828ed101facb8727f1f35ad9a7933c09019b0
parentcb803e58ffc4cbd953a47b3e642daa0cd552ffbe (diff)
Core/PacketIO: Fixed dynamic updatefield handling when values get removed
-rw-r--r--src/server/game/Entities/Item/Item.cpp11
-rw-r--r--src/server/game/Entities/Object/Object.cpp13
-rw-r--r--src/server/game/Entities/Object/Object.h13
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;