aboutsummaryrefslogtreecommitdiff
path: root/src/game/MovementHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/MovementHandler.cpp')
-rw-r--r--src/game/MovementHandler.cpp215
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*/)