void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if (!GetPlayer()->IsBeingTeleportedFar()) return; GetPlayer()->SetSemaphoreTeleportFar(false); // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if (!MapManager::IsValidMapCoord(loc)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId()); InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId()); // reset instance validity, except if going to an instance inside an instance if (GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; Map * oldMap = GetPlayer()->GetMap(); ASSERT(oldMap); if (GetPlayer()->IsInWorld()) { sLog->outCrash("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId()); oldMap->Remove(GetPlayer(), false); } // relocate the player to the teleport destination Map * newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer(), 0); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (!newMap || !newMap->CanEnter(GetPlayer())) { sLog->outError("Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow()); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } else GetPlayer()->Relocate(&loc); GetPlayer()->ResetMap(); GetPlayer()->SetMap(newMap); GetPlayer()->SendInitialPacketsBeforeAddToMap(); if (!GetPlayer()->GetMap()->Add(GetPlayer())) { sLog->outError("WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.GetMapId()); GetPlayer()->ResetMap(); GetPlayer()->SetMap(oldMap); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } // battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if (_player->InBattleground()) { // cleanup setting if outdated if (!mEntry->IsBattlegroundOrArena()) { // We're not in BG _player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE); // reset destination bg team _player->SetBGTeam(0); } // join to bg case else if (Battleground *bg = _player->GetBattleground()) { if (_player->IsInvitedForBattlegroundInstance(_player->GetBattlegroundId())) bg->AddPlayer(_player); } } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if (!_player->InBattleground()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->CleanupAfterTaxiFlight(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if (mEntry->IsDungeon()) { GetPlayer()->ResurrectPlayer(0.5f, false); GetPlayer()->SpawnCorpseBones(); } } bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena(); if (mInstance) { Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid()); if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff)) { if (mapDiff->resetTime) { if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff)) { uint32 timeleft = uint32(timeReset - time(NULL)); GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft); } } } allowMount = mInstance->AllowMount; } // mount allow check if (!allowMount) _player->RemoveAurasByType(SPELL_AURA_MOUNTED); // update zone immediately, otherwise leave channel will cause crash in mtmap uint32 newzone, newarea; GetPlayer()->GetZoneAndAreaId(newzone, newarea); GetPlayer()->UpdateZone(newzone, newarea); // honorless target if (GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // in friendly area else if (GetPlayer()->IsPvP() && !GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) GetPlayer()->UpdatePvP(false, false); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if(!GetPlayer()->IsBeingTeleportedFar()) return; // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player got's teleported far to a not valid location. (map:%u, x:%f, y:%f, z:%f) We log him out and don't save him..", loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); // stop teleportation else we would try this again in the beginning of WorldSession::LogoutPlayer... GetPlayer()->SetSemaphoreTeleportFar(false); // player don't gets saved - so his coords will stay at the point where // he was last saved LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = ObjectMgr::GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleportFar(false); // relocate the player to the teleport destination GetPlayer()->SetMap(MapManager::Instance().CreateMap(loc.mapid, GetPlayer())); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // check this before Map::Add(player), because that will create the instance save! bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId()) == NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if(!GetPlayer()->GetMap()->Add(GetPlayer())) { //if player wasn't added to map, reset his map pointer! GetPlayer()->ResetMap(); DEBUG_LOG("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // teleport the player home GetPlayer()->TeleportToHomebind(); return; } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Reset(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->m_taxi.ClearTaxiDestinations(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry->IsDungeon() ) { GetPlayer()->ResurrectPlayer(0.5f); GetPlayer()->SpawnCorpseBones(); } } if(mEntry->IsRaid() && mInstance) { if(reset_notify) { uint32 timeleft = sInstanceSaveMgr.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance } } // mount allow check if(!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // battleground state prepare // only add to bg group and object, if the player was invited (else he entered through command) if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) { BattleGround *bg = _player->GetBattleGround(); if(bg) { bg->AddPlayer(_player); if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg { // get the team this way, because arenas might 'override' the teams. uint32 team = bg->GetPlayerTeam(_player->GetGUID()); if(!team) team = _player->GetTeam(); if(!bg->GetBgRaid(team)) // first player joined { Group *group = new Group; bg->SetBgRaid(team, group); group->Create(_player->GetGUIDLow(), _player->GetName()); } else // raid already exist { bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName()); } } } } // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if(!GetPlayer()->IsBeingTeleportedFar()) return; if (_player->GetVehicleKit()) _player->GetVehicleKit()->RemoveAllPassengers(); // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far to a not valid location. (map:%u, x:%f, y:%f, " "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); // stop teleportation else we would try this again and again in LogoutPlayer... GetPlayer()->SetSemaphoreTeleportFar(false); // and teleport the player to a valid place GetPlayer()->TeleportToHomebind(); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = ObjectMgr::GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleportFar(false); // relocate the player to the teleport destination GetPlayer()->SetMap(sMapMgr.CreateMap(loc.mapid, GetPlayer())); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); GetPlayer()->m_anti_TeleTime=time(NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if(!GetPlayer()->GetMap()->Add(GetPlayer())) { //if player wasn't added to map, reset his map pointer! GetPlayer()->ResetMap(); sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far but couldn't be added to map. (map:%u, x:%f, y:%f, " "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); // teleport the player home GetPlayer()->TeleportToHomebind(); return; } // battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if(_player->InBattleGround()) { // cleanup setting if outdated if(!mEntry->IsBattleGroundOrArena()) { // We're not in BG _player->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // reset destination bg team _player->SetBGTeam(0); } // join to bg case else if(BattleGround *bg = _player->GetBattleGround()) { if(_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) bg->AddPlayer(_player); } } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Reset(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->m_taxi.ClearTaxiDestinations(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry->IsDungeon() ) { GetPlayer()->ResurrectPlayer(0.5f); GetPlayer()->SpawnCorpseBones(); } } if (mInstance) { Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid()); if(MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID,diff)) { if (mapDiff->resetTime) { if (time_t timeReset = sInstanceSaveMgr.GetScheduler().GetResetTimeFor(mEntry->MapID,diff)) { uint32 timeleft = uint32(timeReset - time(NULL)); GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft); } } } } // mount allow check if(!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); GetPlayer()->Anti__SetLastTeleTime(::time(NULL)); GetPlayer()->m_anti_BeginFallZ=INVALID_HEIGHT; //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if (!GetPlayer()->IsBeingTeleportedFar()) return; GetPlayer()->SetSemaphoreTeleportFar(0); // get the teleport destination WorldLocation const& loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if (!MapManager::IsValidMapCoord(loc)) { KickPlayer(); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId()); InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId()); Map* oldMap = GetPlayer()->GetMap(); if (GetPlayer()->IsInWorld()) { sLog->outError("Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName().c_str(), oldMap->GetId(), loc.GetMapId()); oldMap->RemovePlayerFromMap(GetPlayer(), false); } // reset instance validity, except if going to an instance inside an instance if (GetPlayer()->m_InstanceValid == false && !mInstance) { GetPlayer()->m_InstanceValid = true; // pussywizard: m_InstanceValid can be false only by leaving a group in an instance => so remove temp binds that could not be removed because player was still on the map! if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(GetPlayer()->GetGUIDLow(), oldMap->GetId(), oldMap->GetDifficulty())) sInstanceSaveMgr->PlayerUnbindInstance(GetPlayer()->GetGUIDLow(), oldMap->GetId(), oldMap->GetDifficulty(), true); } // relocate the player to the teleport destination Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer()); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (!newMap || !newMap->CanEnter(GetPlayer())) { sLog->outError("Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow()); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation()); GetPlayer()->ResetMap(); GetPlayer()->SetMap(newMap); GetPlayer()->SendInitialPacketsBeforeAddToMap(); if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer())) { sLog->outError("WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), loc.GetMapId()); GetPlayer()->ResetMap(); GetPlayer()->SetMap(oldMap); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } oldMap->AfterPlayerUnlinkFromMap(); // pussywizard: transport teleport couldn't teleport us to the same map (some other teleport pending, reqs not met, etc.), but we still have transport set until player moves! clear it if map differs (crashfix) if (Transport* t = _player->GetTransport()) if (!t->IsInMap(_player)) { t->RemovePassenger(_player); _player->m_transport = NULL; _player->m_movementInfo.transport.Reset(); _player->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT); } if (!_player->getHostileRefManager().isEmpty()) _player->getHostileRefManager().deleteReferences(); // pussywizard: multithreading crashfix CellCoord pair(Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY())); Cell cell(pair); if (!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid()) { KickPlayer(); return; } newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); // pussywizard: player supposed to enter bg map if (_player->InBattleground()) { // but landed on another map, cleanup data if (!mEntry->IsBattlegroundOrArena()) _player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE, PLAYER_MAX_BATTLEGROUND_QUEUES, false, false, TEAM_NEUTRAL); // everything ok else if (Battleground* bg = _player->GetBattleground()) { if (_player->IsInvitedForBattlegroundInstance()) // GMs are not invited, so they are not added to participants bg->AddPlayer(_player); } } // pussywizard: arena spectator stuff { if (newMap->IsBattleArena() && ((BattlegroundMap*)newMap)->GetBG() && _player->HasPendingSpectatorForBG(((BattlegroundMap*)newMap)->GetInstanceId())) { _player->ClearReceivedSpectatorResetFor(); _player->SetIsSpectator(true); ArenaSpectator::SendCommand(_player, "%sENABLE", SPECTATOR_ADDON_PREFIX); ((BattlegroundMap*)newMap)->GetBG()->AddSpectator(_player); ArenaSpectator::HandleResetCommand(_player); } else _player->SetIsSpectator(false); GetPlayer()->SetPendingSpectatorForBG(0); timeWhoCommandAllowed = time(NULL) + sWorld->GetNextWhoListUpdateDelaySecs() + 1; // after exiting arena Subscribe will scan for a player and cached data says he is still in arena, so disallow until next update if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId()) { if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId)) tbg->RemoveToBeTeleported(_player->GetGUID()); _player->SetPendingSpectatorInviteInstanceId(0); } } // xinef: do this again, player can be teleported inside bg->AddPlayer(_player)!!!! CellCoord pair2(Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY())); Cell cell2(pair2); if (!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid()) { KickPlayer(); return; } newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); GetPlayer()->SendInitialPacketsAfterAddToMap(); // resurrect character at enter into instance where his corpse exist after add to map Corpse* corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if (mEntry->IsDungeon()) { GetPlayer()->ResurrectPlayer(0.5f, false); GetPlayer()->SpawnCorpseBones(); } } bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena(); if (mInstance) { Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid()); if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff)) if (mapDiff->resetTime) if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff)) { uint32 timeleft = uint32(timeReset - time(NULL)); GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true); } allowMount = mInstance->AllowMount; } // mount allow check if (!allowMount) _player->RemoveAurasByType(SPELL_AURA_MOUNTED); // update zone immediately, otherwise leave channel will cause crash in mtmap uint32 newzone, newarea; GetPlayer()->GetZoneAndAreaId(newzone, newarea, true); GetPlayer()->UpdateZone(newzone, newarea); // honorless target if (GetPlayer()->pvpInfo.IsHostile) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // in friendly area else if (GetPlayer()->IsPvP() && !GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) GetPlayer()->UpdatePvP(false, false); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug( "WORLD: got MSG_MOVE_WORLDPORT_ACK." ); MapEntry const* mEntry = sMapStore.LookupEntry(GetPlayer()->GetMapId()); if(!mEntry || !MaNGOS::IsValidMapCoord(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY())) { LogoutPlayer(false); return; } // reset instance validity GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleport(false); GetPlayer()->SendInitialPacketsBeforeAddToMap(); MapManager::Instance().GetMap(GetPlayer()->GetMapId(), GetPlayer())->Add(GetPlayer()); GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->top()->GetMovementGeneratorType()==FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); SendPath(flight->GetPath(),flight->GetCurrentNode(),flight->GetPathAtMapEnd()); GetPlayer()->SetDontMove(false); return; } // battleground state prepre, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->FlightComplete(); GetPlayer()->ClearTaxiDestinations(); GetPlayer()->StopMoving(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() == CORPSE_RESURRECTABLE && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry && (mEntry->map_type == MAP_INSTANCE || mEntry->map_type == MAP_RAID) ) { GetPlayer()->ResurrectPlayer(0.5f,false); GetPlayer()->SpawnCorpseBones(); GetPlayer()->SaveToDB(); } } // mount allow check if(!_player->GetBaseMap()->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // battleground state preper if(_player->InBattleGround()) { BattleGround *bg = _player->GetBattleGround(); if(bg) { if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg { if(!bg->GetBgRaid(_player->GetTeam())) // first player joined { Group *group = new Group; bg->SetBgRaid(_player->GetTeam(), group); group->ConvertToRaid(); group->AddMember(_player->GetGUID(), _player->GetName()); group->ChangeLeader(_player->GetGUID()); } else // raid already exist { bg->GetBgRaid(_player->GetTeam())->AddMember(_player->GetGUID(), _player->GetName()); } } } } // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet if(GetPlayer()->m_oldpetnumber) { Pet* NewPet = new Pet(GetPlayer()); if(!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_oldpetnumber, true)) delete NewPet; GetPlayer()->m_oldpetnumber = 0; } GetPlayer()->SetDontMove(false); }
void WorldSession::HandleMoveWorldportAckOpcode() { // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid,loc.x,loc.y,loc.z,loc.o)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleport(false); // relocate the player to the teleport destination GetPlayer()->SetMapId(loc.mapid); GetPlayer()->Relocate(loc.x, loc.y, loc.z, loc.o); // since the MapId is set before the GetInstance call, the InstanceId must be set to 0 // to let GetInstance() determine the proper InstanceId based on the player's binds GetPlayer()->SetInstanceId(0); // check this before Map::Add(player), because that will create the instance save! bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty()) == NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if(!GetPlayer()->GetMap()->Add(GetPlayer())) { sLog.outDebug("WORLD: teleport of player %s (%d) to location %d,%f,%f,%f,%f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.x, loc.y, loc.z, loc.o); // teleport the player home GetPlayer()->SetDontMove(false); if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation())) { // the player must always be able to teleport home sLog.outError("WORLD: failed to teleport player %s (%d) to homebind location %d,%f,%f,%f,%f!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); assert(false); } return; } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight GetPlayer()->SetDontMove(false); FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->m_taxi.ClearTaxiDestinations(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry->IsDungeon() ) { GetPlayer()->ResurrectPlayer(0.5f); GetPlayer()->SpawnCorpseBones(); GetPlayer()->SaveToDB(); } } if(mEntry->IsRaid() && mInstance) { if(reset_notify) { uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance } } // mount allow check if(!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // battleground state prepare // only add to bg group and object, if the player was invited (else he entered through command) if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) { BattleGround *bg = _player->GetBattleGround(); if(bg) { bg->AddPlayer(_player); if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg { // get the team this way, because arenas might 'override' the teams. uint32 team = bg->GetPlayerTeam(_player->GetGUID()); if(!team) team = _player->GetTeam(); if(!bg->GetBgRaid(team)) // first player joined { Group *group = new Group; bg->SetBgRaid(team, group); group->Create(_player->GetGUIDLow(), _player->GetName()); } else // raid already exist { bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName()); } } } } // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet if(GetPlayer()->m_temporaryUnsummonedPetNumber) { Pet* NewPet = new Pet; if(!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true)) delete NewPet; GetPlayer()->m_temporaryUnsummonedPetNumber = 0; } GetPlayer()->SetDontMove(false); }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if(!GetPlayer()->IsBeingTeleportedFar()) return; // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleportFar(false); // relocate the player to the teleport destination GetPlayer()->SetMapId(loc.mapid); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // since the MapId is set before the GetInstance call, the InstanceId must be set to 0 // to let GetInstance() determine the proper InstanceId based on the player's binds GetPlayer()->SetInstanceId(0); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if(!GetPlayer()->GetMap()->Add(GetPlayer())) { sLog.outDebug("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // teleport the player home if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation())) { // the player must always be able to teleport home sLog.outError("WORLD: failed to teleport player %s (%d) to homebind location %d, %f, %f, %f, %f!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); assert(false); } return; } // battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if(_player->InBattleGround()) { // cleanup setting if outdated if(!mEntry->IsBattleGroundOrArena()) { // We're not in BG _player->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // reset destination bg team _player->SetBGTeam(0); } // join to bg case else if(BattleGround *bg = _player->GetBattleGround()) { if(_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) bg->AddPlayer(_player); } } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->m_taxi.ClearTaxiDestinations(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry->IsDungeon() ) { GetPlayer()->ResurrectPlayer(0.5f); GetPlayer()->SpawnCorpseBones(); GetPlayer()->SaveToDB(); } } if((mEntry->IsRaid() || (mEntry->IsNonRaidDungeon() && mEntry->SupportsHeroicMode() && GetPlayer()->IsHeroic())) && mInstance) { uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty(), timeleft); } // mount allow check if(!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if (!GetPlayer()->IsBeingTeleportedFar()) return; // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if (!MapManager::IsValidMapCoord(loc)) { sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far to a not valid location. (map:%u, x:%f, y:%f, " "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ()); // stop teleportation else we would try this again and again in LogoutPlayer... GetPlayer()->SetSemaphoreTeleportFar(false); // and teleport the player to a valid place GetPlayer()->TeleportToHomebind(); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId()); InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.GetMapId()); // reset instance validity, except if going to an instance inside an instance if (GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleportFar(false); Map* oldMap = GetPlayer()->GetMap(); ASSERT(oldMap); if (GetPlayer()->IsInWorld()) { sLog.outCrash("Player is still in world when teleported from map %u! to new map %u", oldMap->GetId(), loc.GetMapId()); oldMap->Remove(GetPlayer(), false); } // relocate the player to the teleport destination Map* newMap = MapManager::Instance().CreateMap(loc.GetMapId(), GetPlayer(), 0); if (!newMap) { sLog.outError("Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow()); GetPlayer()->TeleportToHomebind(); return; } else GetPlayer()->Relocate(&loc); GetPlayer()->ResetMap(); GetPlayer()->SetMap(newMap); // check this before Map::Add(player), because that will create the instance save! bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty()) == NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); if (!GetPlayer()->GetMap()->Add(GetPlayer())) { sLog.outError("WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.GetMapId()); GetPlayer()->ResetMap(); GetPlayer()->SetMap(oldMap); GetPlayer()->TeleportToHomebind(); return; } // battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if (GetPlayer()->InBattleGround()) { // cleanup setting if outdated if (!mEntry->IsBattleGroundOrArena()) { // We're not in BG GetPlayer()->SetBattleGroundId(0); // We're not in BG. // reset destination bg team GetPlayer()->SetBGTeam(0); } // join to bg case else if (BattleGround* bg = GetPlayer()->GetBattleGround()) { if (GetPlayer()->IsInvitedForBattleGroundInstance(GetPlayer()->GetBattleGroundId())) bg->AddPlayer(GetPlayer()); } } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if (!GetPlayer()->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->CleanupAfterTaxiFlight(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse* corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if (mEntry->IsDungeon()) { GetPlayer()->ResurrectPlayer(0.5f, false); GetPlayer()->SpawnCorpseBones(); } } if (mEntry->IsRaid() && mInstance) { if (reset_notify) { uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance } } // mount allow check if (!mEntry->IsMountAllowed()) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // honorless target if (GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet if (GetPlayer()->m_temporaryUnsummonedPetNumber) { Pet* NewPet = new Pet(GetPlayer()); if (!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true)) delete NewPet; GetPlayer()->m_temporaryUnsummonedPetNumber = 0; } //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleMoveWorldportAckOpcode() { // get start teleport coordinates (will used later in fail case) WorldLocation old_loc; GetPlayer()->GetPosition(old_loc); // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if (!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { // stop teleportation else we would try this again and again in LogoutPlayer... GetPlayer()->SetSemaphoreTeleport(false); // player don't gets saved - so his coords will stay at the point where // he was last saved LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); Map *map = NULL; // prevent crash at attempt landing to not existed battleground instance if(mEntry->IsBattleGroundOrArena()) { if (GetPlayer()->GetBattleGroundId()) map = sMapMgr.FindMap(loc.mapid, GetPlayer()->GetBattleGroundId()); if (!map) { GetPlayer()->SetSemaphoreTeleport(false); // Teleport to previous place, if cannot be ported back TP to homebind place if (!GetPlayer()->TeleportTo(old_loc)) GetPlayer()->TeleportToHomebind(); return; } } InstanceTemplate const* mInstance = ObjectMgr::GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if (GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleport(false); // relocate the player to the teleport destination if (!map) map = sMapMgr.CreateMap(loc.mapid, GetPlayer()); GetPlayer()->SetMapId(loc.mapid); GetPlayer()->SetMap(map); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // since the MapId is set before the GetInstance call, the InstanceId must be set to 0 // to let GetInstance() determine the proper InstanceId based on the player's binds GetPlayer()->SetInstanceId(map->GetInstanceId()); // check this before Map::Add(player), because that will create the instance save! bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty()) == NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (!GetPlayer()->GetMap()->Add(GetPlayer())) { // Teleport to previous place, if cannot be ported back TP to homebind place if (!GetPlayer()->TeleportTo(old_loc)) GetPlayer()->TeleportToHomebind(); return; } //this will set player's team ... so IT MUST BE CALLED BEFORE SendInitialPacketsAfterAddToMap() // battleground state prepare (in case join to BG), at relogin/tele player not invited // only add to bg group and object, if the player was invited (else he entered through command) if (_player->InBattleGround()) { // cleanup seting if outdated if (!mEntry->IsBattleGroundOrArena()) { // Do next only if found in battleground _player->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG. // reset destination bg team _player->SetBGTeam(TEAM_NONE); } // join to bg case else if (BattleGround *bg = _player->GetBattleGround()) { if (_player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) bg->AddPlayer(_player); } } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) { if (!_player->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Reset(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetUnitStateMgr().InitDefaults(true); GetPlayer()->CleanupAfterTaxiFlight(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if (mEntry->IsDungeon()) { GetPlayer()->ResurrectPlayer(0.5f,false); GetPlayer()->SpawnCorpseBones(); } } if (mEntry->IsRaid() && mInstance) { if (reset_notify) { uint32 timeleft = sInstanceSaveManager.GetResetTimefor (GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance } } // mount allow check if (!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // honorless target if (GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet if (GetPlayer()->m_temporaryUnsummonedPetNumber) { Pet* NewPet = new Pet; if (!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true)) delete NewPet; GetPlayer()->m_temporaryUnsummonedPetNumber = 0; } }