diff --git a/src/server/game/Entities/Object/MovementInfo.cpp b/src/server/game/Entities/Object/MovementInfo.cpp index ce3a44068c..bdb8fea149 100644 --- a/src/server/game/Entities/Object/MovementInfo.cpp +++ b/src/server/game/Entities/Object/MovementInfo.cpp @@ -59,8 +59,7 @@ bool MovementInfo::HasSpline() const bool MovementInfo::HasHeightChangeFailed() const { - // Todo: handle this - return false; + return heightChangeFailed; } bool MovementInfo::HasTime() const diff --git a/src/server/game/Entities/Object/MovementInfo.h b/src/server/game/Entities/Object/MovementInfo.h index 4edb9dee00..b7c2e39e73 100644 --- a/src/server/game/Entities/Object/MovementInfo.h +++ b/src/server/game/Entities/Object/MovementInfo.h @@ -72,8 +72,11 @@ struct MovementInfo // spline float splineElevation; + // height change + bool heightChangeFailed; + MovementInfo() : - flags(0), flags2(0), time(0), pitch(0.0f), splineElevation(0.0f) + flags(0), flags2(0), time(0), pitch(0.0f), splineElevation(0.0f), heightChangeFailed(false) { pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); transport.Reset(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 301e426610..b62c1d84a0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1531,11 +1531,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // near teleport, triggering send CMSG_MOVE_TELEPORT_ACK from client at landing if (!GetSession()->PlayerLogout()) { - Position oldPos = GetPosition(); - if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) - z += GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - Relocate(x, y, z, orientation); - SendTeleportPacket(oldPos); // this automatically relocates to oldPos in order to broadcast the packet in the right place + m_teleport_dest.m_positionZ += GetHoverOffset(); + SendTeleportPacket(m_teleport_dest); } } else diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 38afb0315a..957a16f16c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13995,80 +13995,40 @@ void Unit::SendTeleportPacket(Position const& pos) // SMSG_MOVE_UPDATE_TELEPORT is sent to nearby players to signal the teleport // MSG_MOVE_TELEPORT is sent to self in order to trigger MSG_MOVE_TELEPORT_ACK and update the position server side - // This oldPos actually contains the destination position if the Unit is a Player. - Position oldPos = {GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()}; + WorldPackets::Movement::MoveUpdateTeleport moveUpdateTeleport; + moveUpdateTeleport.Status = &m_movementInfo; - if (GetTypeId() == TYPEID_UNIT) - Relocate(&pos); // Relocate the unit to its new position in order to build the packets correctly. + Unit* broadcastSource = this; - ObjectGuid guid = GetGUID(); - ObjectGuid transGuid = GetTransGUID(); - - WorldPacket data(SMSG_MOVE_UPDATE_TELEPORT, 38); - WriteMovementInfo(data); - - if (GetTypeId() == TYPEID_PLAYER) + if (Player* playerMover = GetPlayerBeingMoved()) { - WorldPacket data2(MSG_MOVE_TELEPORT, 38); - data2.WriteBit(guid[6]); - data2.WriteBit(guid[0]); - data2.WriteBit(guid[3]); - data2.WriteBit(guid[2]); - data2.WriteBit(uint64(transGuid)); - data2.WriteBit(bool(GetVehicle())); // unknown - data2.WriteBit(guid[1]); - if (transGuid) - { - data2.WriteBit(transGuid[1]); - data2.WriteBit(transGuid[3]); - data2.WriteBit(transGuid[2]); - data2.WriteBit(transGuid[5]); - data2.WriteBit(transGuid[0]); - data2.WriteBit(transGuid[7]); - data2.WriteBit(transGuid[6]); - data2.WriteBit(transGuid[4]); - } - data2.WriteBit(guid[4]); - data2.WriteBit(guid[7]); - data2.WriteBit(guid[5]); - data2.FlushBits(); + float x, y, z, o; + pos.GetPosition(x, y, z, o); + if (TransportBase* transportBase = GetDirectTransport()) + transportBase->CalculatePassengerOffset(x, y, z, &o); - if (transGuid) - { - data2.WriteByteSeq(transGuid[6]); - data2.WriteByteSeq(transGuid[5]); - data2.WriteByteSeq(transGuid[1]); - data2.WriteByteSeq(transGuid[7]); - data2.WriteByteSeq(transGuid[0]); - data2.WriteByteSeq(transGuid[2]); - data2.WriteByteSeq(transGuid[4]); - data2.WriteByteSeq(transGuid[3]); - } + WorldPackets::Movement::MoveTeleport moveTeleport; + moveTeleport.MoverGUID = GetGUID(); + moveTeleport.Pos = Position(x, y, z); + if (GetTransGUID()) + moveTeleport.TransportGUID = GetTransGUID(); + moveTeleport.Facing = o; + moveTeleport.SequenceIndex = m_movementCounter++; + playerMover->SendDirectMessage(moveTeleport.Write()); - data2 << uint32(0); // counter - data2.WriteByteSeq(guid[1]); - data2.WriteByteSeq(guid[2]); - data2.WriteByteSeq(guid[3]); - data2.WriteByteSeq(guid[5]); - data2 << float(GetPositionX()); - data2.WriteByteSeq(guid[4]); - data2 << float(GetOrientation()); - data2.WriteByteSeq(guid[7]); - data2 << float(GetPositionZ()); - data2.WriteByteSeq(guid[0]); - data2.WriteByteSeq(guid[6]); - data2 << float(GetPositionY()); - ToPlayer()->SendDirectMessage(&data2); // Send the MSG_MOVE_TELEPORT packet to self. + broadcastSource = playerMover; + } + else + { + // This is the only packet sent for creatures which contains MovementInfo structure + // we do not update m_movementInfo for creatures so it needs to be done manually here + moveUpdateTeleport.Status->guid = GetGUID(); + moveUpdateTeleport.Status->pos.Relocate(pos); + moveUpdateTeleport.Status->time = GameTime::GetGameTimeMS(); } - // Relocate the player/creature to its old position, so we can broadcast to nearby players correctly - if (GetTypeId() == TYPEID_PLAYER) - Relocate(&pos); - else - Relocate(&oldPos); - // Broadcast the packet to everyone except self. - SendMessageToSet(&data, false); + broadcastSource->SendMessageToSet(moveUpdateTeleport.Write(), false); } bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index df3f780688..f899bcbdcf 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -232,41 +232,16 @@ void WorldSession::HandleSuspendTokenResponse(WorldPackets::Movement::SuspendTok _player->SendSavedInstances(); } -void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) +void WorldSession::HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck& packet) { - TC_LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK"); - - ObjectGuid guid; - uint32 flags, time; - recvPacket >> flags >> time; - - guid[5] = recvPacket.ReadBit(); - guid[0] = recvPacket.ReadBit(); - guid[1] = recvPacket.ReadBit(); - guid[6] = recvPacket.ReadBit(); - guid[3] = recvPacket.ReadBit(); - guid[7] = recvPacket.ReadBit(); - guid[2] = recvPacket.ReadBit(); - guid[4] = recvPacket.ReadBit(); - - recvPacket.ReadByteSeq(guid[4]); - recvPacket.ReadByteSeq(guid[2]); - recvPacket.ReadByteSeq(guid[7]); - recvPacket.ReadByteSeq(guid[6]); - recvPacket.ReadByteSeq(guid[5]); - recvPacket.ReadByteSeq(guid[1]); - recvPacket.ReadByteSeq(guid[3]); - recvPacket.ReadByteSeq(guid[0]); - - TC_LOG_DEBUG("network", "Guid " UI64FMTD, uint64(guid)); - TC_LOG_DEBUG("network", "Flags %u, time %u", flags, time/IN_MILLISECONDS); + TC_LOG_DEBUG("network", "CMSG_MOVE_TELEPORT_ACK: Guid: %s, Sequence: %u, Time: %u", packet.MoverGUID.ToString().c_str(), packet.AckIndex, packet.MoveTime); Player* plMover = _player->m_unitMovedByMe->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; - if (guid != plMover->GetGUID()) + if (packet.MoverGUID != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(false); @@ -275,8 +250,13 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket) WorldLocation const& dest = plMover->GetTeleportDest(); + WorldPackets::Movement::MoveUpdateTeleport moveUpdateTeleport; + moveUpdateTeleport.Status = &plMover->m_movementInfo; + moveUpdateTeleport.Status->pos.Relocate(dest); + plMover->SendMessageToSet(moveUpdateTeleport.Write(), false); + plMover->UpdatePosition(dest, true); - plMover->SetFallInformation(0, GetPlayer()->GetPositionZ()); + plMover->SetFallInformation(0, plMover->GetPositionZ()); uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea); @@ -580,33 +560,11 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) } } -void WorldSession::HandleSetActiveMoverOpcode(WorldPacket& recvPacket) +void WorldSession::HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover& packet) { - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); - - ObjectGuid guid; - - guid[7] = recvPacket.ReadBit(); - guid[2] = recvPacket.ReadBit(); - guid[1] = recvPacket.ReadBit(); - guid[0] = recvPacket.ReadBit(); - guid[4] = recvPacket.ReadBit(); - guid[5] = recvPacket.ReadBit(); - guid[6] = recvPacket.ReadBit(); - guid[3] = recvPacket.ReadBit(); - - recvPacket.ReadByteSeq(guid[3]); - recvPacket.ReadByteSeq(guid[2]); - recvPacket.ReadByteSeq(guid[4]); - recvPacket.ReadByteSeq(guid[0]); - recvPacket.ReadByteSeq(guid[5]); - recvPacket.ReadByteSeq(guid[1]); - recvPacket.ReadByteSeq(guid[6]); - recvPacket.ReadByteSeq(guid[7]); - if (GetPlayer()->IsInWorld()) - if (_player->m_unitMovedByMe->GetGUID() != guid) - TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s" , guid.ToString().c_str(), _player->m_unitMovedByMe->GetGUID().ToString().c_str()); + if (_player->m_unitMovedByMe->GetGUID() != packet.ActiveMover) + TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s" , packet.ActiveMover.ToString().c_str(), _player->m_unitMovedByMe->GetGUID().ToString().c_str()); } void WorldSession::HandleMoveNotActiveMover(WorldPacket &recvData) diff --git a/src/server/game/Movement/MovementStructures.cpp b/src/server/game/Movement/MovementStructures.cpp index e78fecfa55..efb38aedd4 100644 --- a/src/server/game/Movement/MovementStructures.cpp +++ b/src/server/game/Movement/MovementStructures.cpp @@ -1985,79 +1985,6 @@ MovementStatusElements const DismissControlledVehicle[] = MSEEnd, }; -MovementStatusElements const MoveUpdateTeleport[] = -{ - MSEPositionZ, - MSEPositionY, - MSEPositionX, - MSEHasOrientation, - MSEHasSpline, - MSEHasMovementFlags, - MSEHasGuidByte2, - MSEHasGuidByte4, - MSEHasGuidByte6, - MSEHasFallData, - MSEHasGuidByte0, - MSEHasTransportData, - MSEHasGuidByte5, - MSEHasTransportGuidByte1, - MSEHasTransportGuidByte4, - MSEHasTransportGuidByte5, - MSEHasTransportGuidByte3, - MSEHasTransportGuidByte0, - MSEHasTransportTime2, - MSEHasTransportGuidByte7, - MSEHasTransportGuidByte6, - MSEHasVehicleId, - MSEHasTransportGuidByte2, - MSEZeroBit, - MSEHasGuidByte7, - MSEHasGuidByte3, - MSEHasPitch, - MSEHasMovementFlags2, - MSEHasTimestamp, - MSEHasFallDirection, - MSEMovementFlags2, - MSEHasSplineElevation, - MSEMovementFlags, - MSEHasGuidByte1, - MSEFlushBits, - MSEGuidByte7, - MSETransportGuidByte3, - MSETransportGuidByte4, - MSETransportOrientation, - MSETransportVehicleId, - MSETransportGuidByte1, - MSETransportTime2, - MSETransportPositionZ, - MSETransportGuidByte7, - MSETransportGuidByte0, - MSETransportGuidByte6, - MSETransportGuidByte5, - MSETransportGuidByte2, - MSETransportSeat, - MSETransportTime, - MSETransportPositionY, - MSETransportPositionX, - MSEGuidByte6, - MSEPitch, - MSESplineElevation, - MSEOrientation, - MSEGuidByte2, - MSEGuidByte3, - MSEGuidByte1, - MSEFallTime, - MSEFallHorizontalSpeed, - MSEFallCosAngle, - MSEFallSinAngle, - MSEFallVerticalSpeed, - MSEGuidByte5, - MSEGuidByte4, - MSETimestamp, - MSEGuidByte0, - MSEEnd -}; - MovementStatusElements const MovementSetRunMode[] = { MSEPositionY, @@ -5702,8 +5629,6 @@ MovementStatusElements const* GetMovementStatusElementsSequence(uint32 opcode) return MoveNotActiveMover; case CMSG_DISMISS_CONTROLLED_VEHICLE: return DismissControlledVehicle; - case SMSG_MOVE_UPDATE_TELEPORT: - return MoveUpdateTeleport; case CMSG_FORCE_MOVE_ROOT_ACK: return ForceMoveRootAck; case CMSG_FORCE_MOVE_UNROOT_ACK: diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 9b32ad93e8..d7fe09356d 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -129,3 +129,242 @@ WorldPacket const* WorldPackets::Movement::MoveKnockBack::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Movement::MoveTeleport::Write() +{ + _worldPacket.WriteBit(MoverGUID[6]); + _worldPacket.WriteBit(MoverGUID[0]); + _worldPacket.WriteBit(MoverGUID[3]); + _worldPacket.WriteBit(MoverGUID[2]); + + _worldPacket.WriteBit(Vehicle.is_initialized()); + if (Vehicle) + { + _worldPacket.WriteBit(Vehicle->VehicleExitVoluntary); + _worldPacket.WriteBit(Vehicle->VehicleExitTeleport); + } + + _worldPacket.WriteBit(TransportGUID.is_initialized()); + _worldPacket.WriteBit(MoverGUID[1]); + + if (TransportGUID.is_initialized()) + { + ObjectGuid transGUID = TransportGUID.get(); + _worldPacket.WriteBit(transGUID[1]); + _worldPacket.WriteBit(transGUID[3]); + _worldPacket.WriteBit(transGUID[2]); + _worldPacket.WriteBit(transGUID[5]); + _worldPacket.WriteBit(transGUID[0]); + _worldPacket.WriteBit(transGUID[7]); + _worldPacket.WriteBit(transGUID[6]); + _worldPacket.WriteBit(transGUID[4]); + } + + _worldPacket.WriteBit(MoverGUID[4]); + _worldPacket.WriteBit(MoverGUID[7]); + _worldPacket.WriteBit(MoverGUID[5]); + + _worldPacket.FlushBits(); + + if (TransportGUID.is_initialized()) + { + ObjectGuid transGUID = TransportGUID.get(); + _worldPacket.WriteByteSeq(transGUID[5]); + _worldPacket.WriteByteSeq(transGUID[6]); + _worldPacket.WriteByteSeq(transGUID[1]); + _worldPacket.WriteByteSeq(transGUID[7]); + _worldPacket.WriteByteSeq(transGUID[0]); + _worldPacket.WriteByteSeq(transGUID[2]); + _worldPacket.WriteByteSeq(transGUID[4]); + _worldPacket.WriteByteSeq(transGUID[3]); + } + + _worldPacket << uint32(SequenceIndex); + _worldPacket.WriteByteSeq(MoverGUID[1]); + _worldPacket.WriteByteSeq(MoverGUID[2]); + _worldPacket.WriteByteSeq(MoverGUID[3]); + _worldPacket.WriteByteSeq(MoverGUID[5]); + _worldPacket << float(Pos.Pos.GetPositionX()); + _worldPacket.WriteByteSeq(MoverGUID[4]); + _worldPacket << float(Facing); + _worldPacket.WriteByteSeq(MoverGUID[7]); + _worldPacket << float(Pos.Pos.GetPositionZ()); + + if (Vehicle) + _worldPacket << uint32(Vehicle->VehicleSeatIndex); + + _worldPacket.WriteByteSeq(MoverGUID[0]); + _worldPacket.WriteByteSeq(MoverGUID[6]); + + _worldPacket << float(Pos.Pos.GetPositionY()); + + return &_worldPacket; +} + +void WorldPackets::Movement::MoveTeleportAck::Read() +{ + _worldPacket >> int32(AckIndex); + _worldPacket >> int32(MoveTime); + + MoverGUID[5] = _worldPacket.ReadBit(); + MoverGUID[0] = _worldPacket.ReadBit(); + MoverGUID[1] = _worldPacket.ReadBit(); + MoverGUID[6] = _worldPacket.ReadBit(); + MoverGUID[3] = _worldPacket.ReadBit(); + MoverGUID[7] = _worldPacket.ReadBit(); + MoverGUID[2] = _worldPacket.ReadBit(); + MoverGUID[4] = _worldPacket.ReadBit(); + + _worldPacket.ReadByteSeq(MoverGUID[4]); + _worldPacket.ReadByteSeq(MoverGUID[2]); + _worldPacket.ReadByteSeq(MoverGUID[7]); + _worldPacket.ReadByteSeq(MoverGUID[6]); + _worldPacket.ReadByteSeq(MoverGUID[5]); + _worldPacket.ReadByteSeq(MoverGUID[1]); + _worldPacket.ReadByteSeq(MoverGUID[3]); + _worldPacket.ReadByteSeq(MoverGUID[0]); +} + +void WorldPackets::Movement::SetActiveMover::Read() +{ + ActiveMover[7] = _worldPacket.ReadBit(); + ActiveMover[2] = _worldPacket.ReadBit(); + ActiveMover[1] = _worldPacket.ReadBit(); + ActiveMover[0] = _worldPacket.ReadBit(); + ActiveMover[4] = _worldPacket.ReadBit(); + ActiveMover[5] = _worldPacket.ReadBit(); + ActiveMover[6] = _worldPacket.ReadBit(); + ActiveMover[3] = _worldPacket.ReadBit(); + + _worldPacket.ReadByteSeq(ActiveMover[3]); + _worldPacket.ReadByteSeq(ActiveMover[2]); + _worldPacket.ReadByteSeq(ActiveMover[4]); + _worldPacket.ReadByteSeq(ActiveMover[0]); + _worldPacket.ReadByteSeq(ActiveMover[5]); + _worldPacket.ReadByteSeq(ActiveMover[1]); + _worldPacket.ReadByteSeq(ActiveMover[6]); + _worldPacket.ReadByteSeq(ActiveMover[7]); +} + +WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write() +{ + _worldPacket << float(Status->pos.GetPositionZ()); + _worldPacket << float(Status->pos.GetPositionY()); + _worldPacket << float(Status->pos.GetPositionX()); + + _worldPacket.WriteBit(!Status->HasOrientation()); + _worldPacket.WriteBit(Status->HasSpline()); + _worldPacket.WriteBit(!Status->HasMovementFlags()); + _worldPacket.WriteBit(Status->guid[2]); + _worldPacket.WriteBit(Status->guid[4]); + _worldPacket.WriteBit(Status->guid[6]); + _worldPacket.WriteBit(Status->HasFallData()); + _worldPacket.WriteBit(Status->guid[0]); + _worldPacket.WriteBit(Status->HasTransportData()); + _worldPacket.WriteBit(Status->guid[5]); + + if (Status->HasTransportData()) + { + _worldPacket.WriteBit(Status->transport.guid[1]); + _worldPacket.WriteBit(Status->transport.guid[4]); + _worldPacket.WriteBit(Status->transport.guid[5]); + _worldPacket.WriteBit(Status->transport.guid[3]); + _worldPacket.WriteBit(Status->transport.guid[0]); + _worldPacket.WriteBit(Status->HasTransportTime2()); + _worldPacket.WriteBit(Status->transport.guid[7]); + _worldPacket.WriteBit(Status->transport.guid[6]); + _worldPacket.WriteBit(Status->HasTransportVehicleId()); + _worldPacket.WriteBit(Status->transport.guid[2]); + } + + _worldPacket.WriteBit(Status->HasHeightChangeFailed()); + _worldPacket.WriteBit(Status->guid[7]); + _worldPacket.WriteBit(Status->guid[3]); + + _worldPacket.WriteBit(!Status->HasPitch()); + _worldPacket.WriteBit(!Status->HasExtraMovementFlags()); + _worldPacket.WriteBit(!Status->HasTime()); + + if (Status->HasFallData()) + _worldPacket.WriteBit(Status->HasFallDirection()); + + if (Status->HasExtraMovementFlags()) + _worldPacket.WriteBits(Status->GetExtraMovementFlags(), 12); + + _worldPacket.WriteBit(!Status->HasSplineElevation()); + + if (Status->HasMovementFlags()) + _worldPacket.WriteBits(Status->GetMovementFlags(), 30); + + _worldPacket.WriteBit(Status->guid[1]); + _worldPacket.FlushBits(); + + _worldPacket.WriteByteSeq(Status->guid[7]); + + if (Status->HasTransportData()) + { + _worldPacket.WriteByteSeq(Status->transport.guid[3]); + _worldPacket.WriteByteSeq(Status->transport.guid[4]); + _worldPacket << float(Status->transport.pos.GetOrientation()); + + if (Status->HasTransportVehicleId()) + _worldPacket << uint32(Status->transport.vehicleId); + + _worldPacket.WriteByteSeq(Status->transport.guid[1]); + + if (Status->HasTransportTime2()) + _worldPacket << uint32(Status->transport.time2); + + _worldPacket << float(Status->transport.pos.GetPositionZ()); + + _worldPacket.WriteByteSeq(Status->transport.guid[7]); + _worldPacket.WriteByteSeq(Status->transport.guid[0]); + _worldPacket.WriteByteSeq(Status->transport.guid[6]); + _worldPacket.WriteByteSeq(Status->transport.guid[5]); + _worldPacket.WriteByteSeq(Status->transport.guid[2]); + + _worldPacket << int8(Status->transport.seat); + _worldPacket << uint32(Status->transport.time); + _worldPacket << float(Status->transport.pos.GetPositionY()); + _worldPacket << float(Status->transport.pos.GetPositionX()); + } + + _worldPacket.WriteByteSeq(Status->guid[6]); + + if (Status->HasPitch()) + _worldPacket << float(Status->pitch); + + if (Status->HasSplineElevation()) + _worldPacket << float(Status->splineElevation); + + if (Status->HasOrientation()) + _worldPacket << float(Status->pos.GetOrientation()); + + _worldPacket.WriteByteSeq(Status->guid[2]); + _worldPacket.WriteByteSeq(Status->guid[3]); + _worldPacket.WriteByteSeq(Status->guid[1]); + + if (Status->HasFallData()) + { + _worldPacket << uint32(Status->GetFallTime()); + + if (Status->HasFallDirection()) + { + _worldPacket << float(Status->jump.xyspeed); + _worldPacket << float(Status->jump.cosAngle); + _worldPacket << float(Status->jump.sinAngle); + } + + _worldPacket << float(Status->jump.zspeed); + } + + _worldPacket.WriteByteSeq(Status->guid[5]); + _worldPacket.WriteByteSeq(Status->guid[4]); + + if (Status->HasTime()) + _worldPacket << uint32(Status->time); + + _worldPacket.WriteByteSeq(Status->guid[0]); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 57f27d89b9..2a1258553b 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -113,6 +113,60 @@ namespace WorldPackets MoveKnockBackSpeeds Speeds; uint32 SequenceIndex = 0; }; + + struct VehicleTeleport + { + uint8 VehicleSeatIndex = 0; + bool VehicleExitVoluntary = false; + bool VehicleExitTeleport = false; + }; + + class MoveTeleport final : public ServerPacket + { + public: + MoveTeleport() : ServerPacket(OpcodeServer(MSG_MOVE_TELEPORT), 12 + 4 + 8 + 8 + 4) { } + + WorldPacket const* Write() override; + + TaggedPosition Pos; + Optional Vehicle; + uint32 SequenceIndex = 0; + ObjectGuid MoverGUID; + Optional TransportGUID; + float Facing = 0.0f; + }; + + class MoveTeleportAck final : public ClientPacket + { + public: + MoveTeleportAck(WorldPacket&& packet) : ClientPacket(OpcodeClient(MSG_MOVE_TELEPORT_ACK), std::move(packet)) { } + + void Read() override; + + ObjectGuid MoverGUID; + int32 AckIndex = 0; + int32 MoveTime = 0; + }; + + class SetActiveMover final : public ClientPacket + { + public: + SetActiveMover(WorldPacket&& packet) : ClientPacket(CMSG_SET_ACTIVE_MOVER, std::move(packet)) { } + + void Read() override; + + ObjectGuid ActiveMover; + }; + + class MoveUpdateTeleport final : public ServerPacket + { + public: + MoveUpdateTeleport() : ServerPacket(SMSG_MOVE_UPDATE_TELEPORT) { } + + WorldPacket const* Write() override; + + MovementInfo* Status = nullptr; + }; } } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index c2068a43f9..aa7ddc8730 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -143,6 +143,8 @@ namespace WorldPackets namespace Movement { + class MoveTeleportAck; + class SetActiveMover; class SuspendTokenResponse; } @@ -649,7 +651,7 @@ class TC_GAME_API WorldSession // Knockback void HandleMoveKnockBackAck(WorldPacket& recvPacket); void HandleGravityAckMessage(WorldPacket & recvData); - void HandleMoveTeleportAck(WorldPacket& recvPacket); + void HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck& packet); void HandleForceSpeedChangeAck(WorldPacket& recvData); void HandleSetCollisionHeightAck(WorldPacket& recvData); @@ -721,7 +723,7 @@ class TC_GAME_API WorldSession void HandleMovementOpcodes(WorldPacket& recvPacket); void HandleMovementOpcode(uint16 opcode, MovementInfo& movementInfo); - void HandleSetActiveMoverOpcode(WorldPacket& recvData); + void HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover& packet); void HandleMoveNotActiveMover(WorldPacket& recvData); void HandleDismissControlledVehicle(WorldPacket& recvData); void HandleRequestVehicleExit(WorldPacket& recvData);