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, 90 insertions, 125 deletions
diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp
index 0a310cddd96..29f673061b4 100644
--- a/src/game/MovementHandler.cpp
+++ b/src/game/MovementHandler.cpp
@@ -178,64 +178,12 @@ void WorldSession::HandleMoveWorldportAckOpcode()
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{
- CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4);
+ uint32 opcode = recv_data.GetOpcode();
+ sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
/* extract packet */
MovementInfo 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
- }
+ ReadMovementInfo(recv_data, &movementInfo);
/*----------------*/
if(recv_data.size() != recv_data.rpos())
@@ -252,7 +200,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, MovementFlags);
+ HandlePossessedMovement(recv_data, movementInfo, movementInfo.flags);
return;
}
@@ -260,10 +208,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
return;
//Save movement flags
- GetPlayer()->SetUnitMovementFlags(MovementFlags);
+ GetPlayer()->SetUnitMovementFlags(movementInfo.flags);
/* handle special cases */
- if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT)
+ if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
{
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
@@ -282,9 +230,6 @@ 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;
@@ -301,13 +246,14 @@ 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 (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
+ if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
GetPlayer()->HandleFallDamage(movementInfo);
- if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
+ if(((movementInfo.flags & 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) );
@@ -316,14 +262,35 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
/*----------------------*/
/* process position-change */
- 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());
+ 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
data.append(recv_data.contents(), recv_data.size());
GetPlayer()->SendMessageToSet(&data, false);
- GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
- GetPlayer()->m_movementInfo = movementInfo;
+ 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);
+ }
+ }
+
if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);
@@ -396,20 +363,13 @@ void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo&
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
{
- CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4);
+ 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);
/* extract packet */
uint64 guid;
- 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;
+ uint32 unk1;
float newspeed;
recv_data >> guid;
@@ -420,47 +380,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
// continue parse packet
- 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);
+ recv_data >> unk1; // counter or moveEvent
- 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
- }
+ MovementInfo movementInfo;
+ ReadMovementInfo(recv_data, &movementInfo);
// recheck
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4);
@@ -473,7 +396,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" };
+ static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
uint16 opcode = recv_data.GetOpcode();
switch(opcode)
@@ -486,6 +409,7 @@ 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;
@@ -520,20 +444,61 @@ 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;
- WorldPacket data(SMSG_TIME_SYNC_REQ, 4); // new 2.0.x, enable movement
- data << uint32(0x00000000); // on blizz it increments periodically
- SendPacket(&data);
+ 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;
+ }
}
-void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/)
+void WorldSession::HandleMoveNotActiveMover(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*/)