Ejemplo n.º 1
0
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);
    }
}