void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo) { Unit *mover = _player->GetMover(); movementInfo.CorrectData(mover); if (Player* plMover = mover->ToPlayer()) { // ignore current relocation if needed if (plMover->IsNextRelocationIgnored()) { plMover->DoIgnoreRelocation(); return; } if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT)) { GetPlayer()->GetCheatData()->OnTransport(plMover, movementInfo.GetTransportGuid()); Unit* loadPetOnTransport = nullptr; if (!plMover->GetTransport()) if (Transport* t = plMover->GetMap()->GetTransport(movementInfo.GetTransportGuid())) { t->AddPassenger(plMover); if (Pet* pet = plMover->GetPet()) if (pet->GetTransport() != t) loadPetOnTransport = pet; } if (plMover->GetTransport()) { movementInfo.pos.x = movementInfo.GetTransportPos()->x; movementInfo.pos.y = movementInfo.GetTransportPos()->y; movementInfo.pos.z = movementInfo.GetTransportPos()->z; movementInfo.pos.o = movementInfo.GetTransportPos()->o; plMover->GetTransport()->CalculatePassengerPosition(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.z, &movementInfo.pos.o); if (loadPetOnTransport) { loadPetOnTransport->NearTeleportTo(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.z, movementInfo.pos.o); plMover->GetTransport()->AddPassenger(loadPetOnTransport); } } } else if (plMover->GetTransport()) { plMover->GetTransport()->RemovePassenger(plMover); if (Pet* pet = plMover->GetPet()) { // If moving on transport, stop it. pet->DisableSpline(); if (pet->GetTransport()) { pet->GetTransport()->RemovePassenger(pet); pet->NearTeleportTo(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.z, movementInfo.pos.o); } } } if (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING) != plMover->IsInWater()) { // now client not include swimming flag in case jumping under water plMover->SetInWater(!plMover->IsInWater() || plMover->GetTerrain()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z)); } plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o); plMover->m_movementInfo = movementInfo; // super smart decision; rework required if (ObjectGuid lootGuid = plMover->GetLootGuid()) plMover->SendLootRelease(lootGuid); // Nostalrius - antiundermap1 if (movementInfo.HasMovementFlag(MOVEFLAG_FALLINGFAR)) { float hauteur = plMover->GetMap()->GetHeight(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), true); bool undermap = false; // Undermap if ((plMover->GetPositionZ() + 100.0f) < hauteur) undermap = true; if (plMover->GetPositionZ() < 250.0f && plMover->GetMapId() == 489) undermap = true; if (undermap) if (plMover->UndermapRecall()) sLog.outInfo("[UNDERMAP] %s [GUID %u]. MapId:%u %f %f %f", plMover->GetName(), plMover->GetGUIDLow(), plMover->GetMapId(), plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ()); } else if (plMover->CanFreeMove()) plMover->SaveNoUndermapPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z + 3.0f); // Antiundermap2: teleportation au cimetiere if (movementInfo.GetPos()->z < -500.0f) { // NOTE: this is actually called many times while falling // even after the player has been teleported away // TODO: discard movement packets after the player is rooted if (plMover->isAlive()) { // Nostalrius : pas mort quand on chute if (plMover->InBattleGround()) plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetHealth()); else plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetHealth() / 2); // pl can be alive if GM/etc if (!plMover->isAlive()) { // change the death state to CORPSE to prevent the death timer from // starting in the next player update plMover->KillPlayer(); plMover->BuildPlayerRepop(); } } // cancel the death timer here if started sLog.outInfo("[UNDERMAP/Teleport] Player %s teleported.", plMover->GetName(), plMover->GetGUIDLow(), plMover->GetMapId(), plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ()); plMover->RepopAtGraveyard(); } } else // creature charmed { if (mover->IsInWorld()) mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o); } }