fix(Core/Movement): Properly handled root movement acks. (#8019)
Fixes #7892
This commit is contained in:
@@ -17174,44 +17174,16 @@ void Unit::SetStunned(bool apply)
|
|||||||
{
|
{
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
if (m_rootTimes > 0) // blizzard internal check?
|
|
||||||
m_rootTimes++;
|
|
||||||
|
|
||||||
SetTarget();
|
SetTarget();
|
||||||
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||||
|
|
||||||
// MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
|
|
||||||
// this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
|
|
||||||
// setting MOVEMENTFLAG_ROOT
|
|
||||||
RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
|
|
||||||
AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
|
|
||||||
|
|
||||||
if (GetTypeId() == TYPEID_PLAYER)
|
if (GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
|
||||||
WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
|
|
||||||
data << GetPackGUID();
|
|
||||||
data << m_rootTimes;
|
|
||||||
SendMessageToSet(&data, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8);
|
|
||||||
data << GetPackGUID();
|
|
||||||
SendMessageToSet(&data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// xinef: inform client about our current orientation
|
|
||||||
SendMovementFlagUpdate();
|
|
||||||
|
|
||||||
// Creature specific
|
|
||||||
if (GetTypeId() != TYPEID_PLAYER)
|
|
||||||
StopMoving();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
SetStandState(UNIT_STAND_STATE_STAND);
|
SetStandState(UNIT_STAND_STATE_STAND);
|
||||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetRooted(true);
|
||||||
|
|
||||||
CastStop();
|
CastStop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -17236,21 +17208,7 @@ void Unit::SetStunned(bool apply)
|
|||||||
|
|
||||||
if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect
|
if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect
|
||||||
{
|
{
|
||||||
if (GetTypeId() == TYPEID_PLAYER)
|
SetRooted(false);
|
||||||
{
|
|
||||||
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
|
|
||||||
data << GetPackGUID();
|
|
||||||
data << ++m_rootTimes;
|
|
||||||
SendMessageToSet(&data, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
|
|
||||||
data << GetPackGUID();
|
|
||||||
SendMessageToSet(&data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17266,44 +17224,55 @@ void Unit::SetRooted(bool apply)
|
|||||||
// this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
|
// this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
|
||||||
// setting MOVEMENTFLAG_ROOT
|
// setting MOVEMENTFLAG_ROOT
|
||||||
RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
|
RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
|
||||||
AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
|
|
||||||
|
|
||||||
if (GetTypeId() == TYPEID_PLAYER)
|
if (IsFalling())
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
|
AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
|
||||||
data << GetPackGUID();
|
|
||||||
data << m_rootTimes;
|
|
||||||
SendMessageToSet(&data, true);
|
|
||||||
|
|
||||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8);
|
AddUnitMovementFlag(MOVEMENTFLAG_PENDING_ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creature specific
|
||||||
|
if (GetTypeId() != TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
StopMoving();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_movedByPlayer)
|
||||||
|
{
|
||||||
|
WorldPacket data(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size() + 4);
|
||||||
|
data << GetPackGUID();
|
||||||
|
data << m_rootTimes;
|
||||||
|
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorldPacket data(SMSG_SPLINE_MOVE_ROOT, GetPackGUID().size());
|
||||||
data << GetPackGUID();
|
data << GetPackGUID();
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
StopMoving();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT | MOVEMENTFLAG_PENDING_ROOT);
|
||||||
|
|
||||||
if (!HasUnitState(UNIT_STATE_STUNNED)) // prevent moving if it also has stun effect
|
if (!HasUnitState(UNIT_STATE_STUNNED)) // prevent moving if it also has stun effect
|
||||||
{
|
{
|
||||||
if (GetTypeId() == TYPEID_PLAYER)
|
if (m_movedByPlayer)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
|
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size() + 4);
|
||||||
data << GetPackGUID();
|
data << GetPackGUID();
|
||||||
data << ++m_rootTimes;
|
data << m_rootTimes;
|
||||||
SendMessageToSet(&data, true);
|
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
|
WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, GetPackGUID().size());
|
||||||
data << GetPackGUID();
|
data << GetPackGUID();
|
||||||
SendMessageToSet(&data, true);
|
SendMessageToSet(&data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -983,56 +983,6 @@ void WorldSession::HandleFeatherFallAck(WorldPacket& recv_data)
|
|||||||
recv_data.rfinish(); // prevent warnings spam
|
recv_data.rfinish(); // prevent warnings spam
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleMoveUnRootAck(WorldPacket& recv_data)
|
|
||||||
{
|
|
||||||
// no used
|
|
||||||
recv_data.rfinish(); // prevent warnings spam
|
|
||||||
/*
|
|
||||||
ObjectGuid guid;
|
|
||||||
recv_data >> guid;
|
|
||||||
|
|
||||||
// now can skip not our packet
|
|
||||||
if (_player->GetGUID() != guid)
|
|
||||||
{
|
|
||||||
recv_data.rfinish(); // prevent warnings spam
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("network.opcode", "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK");
|
|
||||||
|
|
||||||
recv_data.read_skip<uint32>(); // unk
|
|
||||||
|
|
||||||
MovementInfo movementInfo;
|
|
||||||
movementInfo.guid = guid;
|
|
||||||
ReadMovementInfo(recv_data, &movementInfo);
|
|
||||||
recv_data.read_skip<float>(); // unk2
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleMoveRootAck(WorldPacket& recv_data)
|
|
||||||
{
|
|
||||||
// no used
|
|
||||||
recv_data.rfinish(); // prevent warnings spam
|
|
||||||
/*
|
|
||||||
ObjectGuid guid;
|
|
||||||
recv_data >> guid;
|
|
||||||
|
|
||||||
// now can skip not our packet
|
|
||||||
if (_player->GetGUID() != guid)
|
|
||||||
{
|
|
||||||
recv_data.rfinish(); // prevent warnings spam
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG("network.opcode", "WORLD: CMSG_FORCE_MOVE_ROOT_ACK");
|
|
||||||
|
|
||||||
recv_data.read_skip<uint32>(); // unk
|
|
||||||
|
|
||||||
MovementInfo movementInfo;
|
|
||||||
ReadMovementInfo(recv_data, &movementInfo);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data)
|
void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data)
|
||||||
{
|
{
|
||||||
uint8 ActionBar;
|
uint8 ActionBar;
|
||||||
|
|||||||
@@ -926,3 +926,83 @@ void WorldSession::ComputeNewClockDelta()
|
|||||||
_timeSyncClockDelta = back.first;
|
_timeSyncClockDelta = back.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldSession::HandleMoveRootAck(WorldPacket& recvData)
|
||||||
|
{
|
||||||
|
ObjectGuid guid;
|
||||||
|
recvData >> guid.ReadAsPacked();
|
||||||
|
|
||||||
|
Unit* mover = _player->m_mover;
|
||||||
|
if (!mover || guid != mover->GetGUID())
|
||||||
|
{
|
||||||
|
recvData.rfinish(); // prevent warnings spam
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 movementCounter;
|
||||||
|
recvData >> movementCounter;
|
||||||
|
|
||||||
|
MovementInfo movementInfo;
|
||||||
|
movementInfo.guid = guid;
|
||||||
|
ReadMovementInfo(recvData, &movementInfo);
|
||||||
|
|
||||||
|
/* process position-change */
|
||||||
|
int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta;
|
||||||
|
if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
|
||||||
|
movementInfo.time = getMSTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
movementInfo.time = (uint32)movementTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
movementInfo.guid = mover->GetGUID();
|
||||||
|
mover->m_movementInfo = movementInfo;
|
||||||
|
mover->UpdatePosition(movementInfo.pos);
|
||||||
|
|
||||||
|
WorldPacket data(MSG_MOVE_ROOT, 64);
|
||||||
|
WriteMovementInfo(&data, &movementInfo);
|
||||||
|
mover->SendMessageToSet(&data, _player);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldSession::HandleMoveUnRootAck(WorldPacket& recvData)
|
||||||
|
{
|
||||||
|
ObjectGuid guid;
|
||||||
|
recvData >> guid.ReadAsPacked();
|
||||||
|
|
||||||
|
Unit* mover = _player->m_mover;
|
||||||
|
if (!mover || guid != mover->GetGUID())
|
||||||
|
{
|
||||||
|
recvData.rfinish(); // prevent warnings spam
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 movementCounter;
|
||||||
|
recvData >> movementCounter;
|
||||||
|
|
||||||
|
MovementInfo movementInfo;
|
||||||
|
movementInfo.guid = guid;
|
||||||
|
ReadMovementInfo(recvData, &movementInfo);
|
||||||
|
|
||||||
|
/* process position-change */
|
||||||
|
int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta;
|
||||||
|
if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
|
||||||
|
movementInfo.time = getMSTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
movementInfo.time = (uint32)movementTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
movementInfo.guid = mover->GetGUID();
|
||||||
|
mover->m_movementInfo = movementInfo;
|
||||||
|
mover->UpdatePosition(movementInfo.pos);
|
||||||
|
|
||||||
|
WorldPacket data(MSG_MOVE_UNROOT, 64);
|
||||||
|
WriteMovementInfo(&data, &movementInfo);
|
||||||
|
mover->SendMessageToSet(&data, _player);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user