diff options
Diffstat (limited to 'src/game/MovementHandler.cpp')
-rw-r--r-- | src/game/MovementHandler.cpp | 215 |
1 files changed, 125 insertions, 90 deletions
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 29f673061b4..0a310cddd96 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -178,12 +178,64 @@ void WorldSession::HandleMoveWorldportAckOpcode() void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { - uint32 opcode = recv_data.GetOpcode(); - sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); + CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4); /* extract packet */ MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + uint32 MovementFlags; + + recv_data >> MovementFlags; + recv_data >> movementInfo.unk1; + recv_data >> movementInfo.time; + recv_data >> movementInfo.x; + recv_data >> movementInfo.y; + recv_data >> movementInfo.z; + recv_data >> movementInfo.o; + + if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); + + recv_data >> movementInfo.t_guid; + recv_data >> movementInfo.t_x; + recv_data >> movementInfo.t_y; + recv_data >> movementInfo.t_z; + recv_data >> movementInfo.t_o; + recv_data >> movementInfo.t_time; + } + + if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.fallTime; // duration of last jump (when in jump duration from jump begin to now) + + if(MovementFlags & MOVEMENTFLAG_JUMPING) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); + + recv_data >> movementInfo.j_unk; // constant, but different when jumping in water and on land? + recv_data >> movementInfo.j_sinAngle; // sin of angle between orientation0 and players orientation + recv_data >> movementInfo.j_cosAngle; // cos of angle between orientation0 and players orientation + recv_data >> movementInfo.j_xyspeed; // speed of xy movement + } + + if(MovementFlags & MOVEMENTFLAG_SPLINE) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> movementInfo.u_unk1; // unknown + } /*----------------*/ if(recv_data.size() != recv_data.rpos()) @@ -200,7 +252,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) Unit* pos_unit = GetPlayer()->GetCharm(); if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed { - HandlePossessedMovement(recv_data, movementInfo, movementInfo.flags); + HandlePossessedMovement(recv_data, movementInfo, MovementFlags); return; } @@ -208,10 +260,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) return; //Save movement flags - GetPlayer()->SetUnitMovementFlags(movementInfo.flags); + GetPlayer()->SetUnitMovementFlags(MovementFlags); /* handle special cases */ - if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) + if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) @@ -230,6 +282,9 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { if ((*iter)->GetGUID() == movementInfo.t_guid) { + // unmount before boarding + GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + GetPlayer()->m_transport = (*iter); (*iter)->AddPassenger(GetPlayer()); break; @@ -246,14 +301,13 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) movementInfo.t_z = 0.0f; movementInfo.t_o = 0.0f; movementInfo.t_time = 0; - movementInfo.t_seat = -1; } // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). - if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) + if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) GetPlayer()->HandleFallDamage(movementInfo); - if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) + if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) { // now client not include swimming flag in case jumping under water GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); @@ -262,35 +316,14 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) /*----------------------*/ /* process position-change */ - Unit *mover = _player->m_mover; - recv_data.put<uint32>(6, getMSTime()); // fix time, offset flags(4) + unk(2) - WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size())); - data.append(_player->m_mover->GetPackGUID()); // use mover guid + recv_data.put<uint32>(5, getMSTime()); // offset flags(4) + unk(1) + WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size())); + data.append(GetPlayer()->GetPackGUID()); data.append(recv_data.contents(), recv_data.size()); GetPlayer()->SendMessageToSet(&data, false); - if(!_player->GetCharmGUID()) // nothing is charmed - { - _player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - _player->m_movementInfo = movementInfo; - _player->SetUnitMovementFlags(movementInfo.flags); - } - else - { - if(mover->GetTypeId() != TYPEID_PLAYER) // unit, creature, pet, vehicle... - { - if(Map *map = mover->GetMap()) - map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - mover->SetUnitMovementFlags(movementInfo.flags); - } - else // player - { - ((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - ((Player*)mover)->m_movementInfo = movementInfo; - ((Player*)mover)->SetUnitMovementFlags(movementInfo.flags); - } - } - + GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + GetPlayer()->m_movementInfo = movementInfo; if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND) GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z); @@ -363,13 +396,20 @@ void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) { - sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode()); - - CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4); + CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4); /* extract packet */ uint64 guid; - uint32 unk1; + uint8 unkB; + uint32 unk1, flags, time, fallTime; + float x, y, z, orientation; + + uint64 t_GUID; + float t_x, t_y, t_z, t_o; + uint32 t_time; + float s_pitch; + float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed; + float u_unk1; float newspeed; recv_data >> guid; @@ -380,10 +420,47 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) // continue parse packet - recv_data >> unk1; // counter or moveEvent + recv_data >> unk1; + recv_data >> flags >> unkB >> time; + recv_data >> x >> y >> z >> orientation; + if (flags & MOVEMENTFLAG_ONTRANSPORT) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); - MovementInfo movementInfo; - ReadMovementInfo(recv_data, &movementInfo); + recv_data >> t_GUID; + recv_data >> t_x >> t_y >> t_z >> t_o >> t_time; + } + if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> s_pitch; // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up + } + + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> fallTime; // duration of last jump (when in jump duration from jump begin to now) + + if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING)) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); + + recv_data >> j_unk1; // ?constant, but different when jumping in water and on land? + recv_data >> j_sinAngle >> j_cosAngle; // sin + cos of angle between orientation0 and players orientation + recv_data >> j_xyspeed; // speed of xy movement + } + + if(flags & MOVEMENTFLAG_SPLINE) + { + // recheck + CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); + + recv_data >> u_unk1; // unknown + } // recheck CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); @@ -396,7 +473,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) UnitMoveType move_type; UnitMoveType force_move_type; - static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" }; + static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" }; uint16 opcode = recv_data.GetOpcode(); switch(opcode) @@ -409,7 +486,6 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break; case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break; case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break; - case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break; default: sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode); return; @@ -444,61 +520,20 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data) { sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); - recv_data.hexlike(); - CHECK_PACKET_SIZE(recv_data, 8); + CHECK_PACKET_SIZE(recv_data,8); uint64 guid; recv_data >> guid; - if(_player->m_mover->GetGUID() != guid) - { - sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid); - return; - } + WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement + data << uint32(0x00000000); // on blizz it increments periodically + SendPacket(&data); } -void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) +void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/) { sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER"); - recv_data.hexlike(); - - CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8); - - uint64 old_mover_guid; - recv_data >> old_mover_guid; - - if(_player->m_mover->GetGUID() == old_mover_guid) - { - sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid); - return; - } - - MovementInfo mi; - ReadMovementInfo(recv_data, &mi); - _player->m_movementInfo = mi; -} - -void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) -{ - sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); - recv_data.hexlike(); - - uint64 vehicleGUID = _player->GetCharmGUID(); - - if(!vehicleGUID) // something wrong here... - return; - - MovementInfo mi; - ReadMovementInfo(recv_data, &mi); - _player->m_movementInfo = mi; - - // using charm guid, because we don't have vehicle guid... - if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID)) - { - _player->ExitVehicle(vehicle); - vehicle->Dismiss(); - } } void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/) |