diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8d063e94c..e0ef3abb2 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17174,44 +17174,16 @@ void Unit::SetStunned(bool apply) { if (apply) { - if (m_rootTimes > 0) // blizzard internal check? - m_rootTimes++; - SetTarget(); 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) - { - 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); - sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true); } + SetRooted(true); + CastStop(); } else @@ -17236,21 +17208,7 @@ void Unit::SetStunned(bool apply) if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect { - if (GetTypeId() == TYPEID_PLAYER) - { - 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); + SetRooted(false); } } } @@ -17266,44 +17224,55 @@ void Unit::SetRooted(bool apply) // 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 (IsFalling()) { - WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10); - data << GetPackGUID(); - data << m_rootTimes; - SendMessageToSet(&data, true); - - sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true); + AddUnitMovementFlag(MOVEMENTFLAG_ROOT); } 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(); SendMessageToSet(&data, true); - StopMoving(); } } else { + RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT | MOVEMENTFLAG_PENDING_ROOT); + 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 << ++m_rootTimes; - SendMessageToSet(&data, true); + data << m_rootTimes; + m_movedByPlayer->ToPlayer()->SendDirectMessage(&data); } else { - WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, GetPackGUID().size()); data << GetPackGUID(); SendMessageToSet(&data, true); } - - RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT); } } } diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 323cce46b..c46f3f8c6 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -983,56 +983,6 @@ void WorldSession::HandleFeatherFallAck(WorldPacket& recv_data) 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(); // unk - - MovementInfo movementInfo; - movementInfo.guid = guid; - ReadMovementInfo(recv_data, &movementInfo); - recv_data.read_skip(); // 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(); // unk - - MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); - */ -} - void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data) { uint8 ActionBar; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 3e0cc8bb0..27f7e5a11 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -926,3 +926,83 @@ void WorldSession::ComputeNewClockDelta() _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); +}