mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/PacketIO: Fixed dynamic updatefield handling when values get removed
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user