void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); uint64 vehicleGUID = _player->GetCharmGUID(); if (!vehicleGUID) // something wrong here... { recvData.rfinish(); // prevent warnings spam return; } MovementInfo mi; mi.ReadFromPacket(recvData); mi.Sanitize(_player); _player->m_movementInfo = mi; _player->ExitVehicle(); }
bool WorldSession::HandleMovementInfo(MovementInfo &movementInfo, const uint16 opcode, const size_t packSize, Unit *mover) { ASSERT(mover != NULL); if (movementInfo.guid != mover->GetGUID() || !movementInfo.pos.IsPositionValid()) return false; Player* plrMover = mover->ToPlayer(); if (plrMover && plrMover->IsBeingTeleported()) return false; if (plrMover && plrMover->HasUnitState(UNIT_STATE_CONTROLLED_BY_SERVER) && !CanMovementBeProcessed(opcode)) return false; movementInfo.Sanitize(mover); if (movementInfo.t_guid) { if (movementInfo.t_pos.GetPositionX() > 50.0f || movementInfo.t_pos.GetPositionY() > 50.0f || movementInfo.t_pos.GetPositionZ() > 50.0f) return false; // moved out of transport size if (!Trinity::IsValidMapCoord( movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(), movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation()) ) return false; // just bad coords if (plrMover) { if (!plrMover->GetTransport()) // didn't have transport. now have { for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { plrMover->m_transport = *iter; (*iter)->AddPassenger(plrMover); break; } } } else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid) // changes transport { bool foundNewTransport = false; plrMover->m_transport->RemovePassenger(plrMover); for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { foundNewTransport = true; plrMover->m_transport = *iter; (*iter)->AddPassenger(plrMover); break; } } if (!foundNewTransport) { plrMover->m_transport = NULL; movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); movementInfo.t_time = 0; movementInfo.t_seat = -1; } } else if (movementInfo.pos.m_positionX != movementInfo.t_pos.m_positionX) plrMover->GetTransport()->UpdatePosition(&movementInfo); } if (!mover->GetTransport() && !mover->GetVehicle()) { GameObject* go = mover->GetMap()->GetGameObject(movementInfo.t_guid); if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT) movementInfo.t_guid = 0; } } else if (plrMover && plrMover->GetTransport()) // had transport, no loger have { plrMover->m_transport->RemovePassenger(plrMover); plrMover->m_transport = NULL; movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); movementInfo.t_time = 0; movementInfo.t_seat = -1; } if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->isInFlight()) plrMover->HandleFall(movementInfo); if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater()) { // now client not include swimming flag in case jumping under water plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } if (plrMover) sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode); WorldPacket data(movementInfo.GetSMSGOpcodeForCMSG(Opcodes(opcode)), packSize); movementInfo.time = getMSTime(); movementInfo.guid = mover->GetGUID(); movementInfo.WriteToPacket(data); _player->SendMessageToSet(&data, _player); mover->m_movementInfo = movementInfo; if (mover->GetVehicle()) // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle() { mover->SetOrientation(movementInfo.pos.GetOrientation()); return true; } // Remove pet when starting to fly if (plrMover && plrMover->IsFlying()) plrMover->UnsummonPetTemporaryIfAny(); mover->UpdatePosition(movementInfo.pos); if (plrMover) { plrMover->UpdateFallInformationIfNeed(movementInfo, opcode); float underMapValueZ, upperLimitValueZ; bool check = false; switch (plrMover->GetMapId()) { case 617: // Dalaran Arena underMapValueZ = 3.0f; upperLimitValueZ = 30.0f; break; case 562: // Blades Edge Arena underMapValueZ = -1.0f; upperLimitValueZ = 22.0f; break; case 559: // Nagrand Arena underMapValueZ = -1.0f; upperLimitValueZ = 21.0f; break; case 572: // Ruins of Lordaeron underMapValueZ = -1.0f; upperLimitValueZ = 45.0f; break; case 618: // Ring of Valor underMapValueZ = 28.0f; upperLimitValueZ = 60.0f; break; case 566: // Eye of the storm underMapValueZ = 1000.0f; upperLimitValueZ = MAX_HEIGHT; break; default: AreaTableEntry const* zone = GetAreaEntryByAreaID(plrMover->GetAreaId()); underMapValueZ = zone ? zone->MaxDepth : -500.0f; upperLimitValueZ = MAX_HEIGHT; break; } check = movementInfo.pos.GetPositionZ() < underMapValueZ || movementInfo.pos.GetPositionZ() > upperLimitValueZ; if (check && plrMover->isAlive() && !(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player))) { plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); if (!plrMover->isAlive()) plrMover->KillPlayer(); // prevent death timer plrMover->RepopAtGraveyard(); } } return true; }