Corpse* ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid) { Corpse * ret = GetObjectInWorld(guid, (Corpse*)NULL); if(!ret) return NULL; if(ret->GetMapId() != u.GetMapId()) return NULL; if(ret->GetInstanceId() != u.GetInstanceId()) return NULL; return ret; }
////////////////////////////////////////////////////////////// /// This function handles MSG_CORPSE_QUERY: ////////////////////////////////////////////////////////////// void WorldSession::HandleCorpseQueryOpcode(WorldPacket &recv_data) { DEBUG_LOG("WORLD","HandleCorpseQueryOpcode Received MSG_CORPSE_QUERY"); Corpse* pCorpse; WorldPacket data(MSG_CORPSE_QUERY, 18); if(_player->isDead()) _player->BuildPlayerRepop(); pCorpse = objmgr.GetCorpseByOwner(_player->GetLowGUID()); if(pCorpse) { MapInfo *pPMapinfo = NULL; pPMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pPMapinfo == NULL) data.Initialize(MSG_CORPSE_QUERY); data << uint8(0x01); //show ? if(pPMapinfo != NULL && !(pPMapinfo->type == INSTANCE_NULL || pPMapinfo->type == INSTANCE_PVP)) { data << pPMapinfo->repopmapid; // mapid (that tombstones shown on) data << pPMapinfo->repopx; data << pPMapinfo->repopy; data << pPMapinfo->repopz; } else { data << pCorpse->GetMapId(); // mapid (that tombstones shown on) data << pCorpse->GetPositionX(); data << pCorpse->GetPositionY(); data << pCorpse->GetPositionZ(); } data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) SendPacket(&data); } }
void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recv_data*/) { DETAIL_LOG("WORLD: Received opcode MSG_CORPSE_QUERY"); Corpse* corpse = GetPlayer()->GetCorpse(); if (!corpse) { WorldPacket data(MSG_CORPSE_QUERY, 1); data << uint8(0); // corpse not found SendPacket(&data); return; } uint32 corpsemapid = corpse->GetMapId(); float x = corpse->GetPositionX(); float y = corpse->GetPositionY(); float z = corpse->GetPositionZ(); int32 mapid = corpsemapid; // if corpse at different map if (corpsemapid != _player->GetMapId()) { // search entrance map for proper show entrance if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(corpsemapid)) { if (corpseMapEntry->IsDungeon() && corpseMapEntry->ghost_entrance_map >= 0) { // if corpse map have entrance if (TerrainInfo const* entranceMap = sTerrainMgr.LoadTerrain(corpseMapEntry->ghost_entrance_map)) { mapid = corpseMapEntry->ghost_entrance_map; x = corpseMapEntry->ghost_entrance_x; y = corpseMapEntry->ghost_entrance_y; z = entranceMap->GetHeightStatic(x, y, MAX_HEIGHT); } } } } WorldPacket data(MSG_CORPSE_QUERY, 1 + (6 * 4)); data << uint8(1); // corpse found data << int32(mapid); data << float(x); data << float(y); data << float(z); data << uint32(corpsemapid); data << uint32(0); // unknown SendPacket(&data); }
void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY"); Corpse* corpse = GetPlayer()->GetCorpse(); if (!corpse) { WorldPacket data(MSG_CORPSE_QUERY, 1); data << uint8(0); // corpse not found SendPacket(&data); return; } uint32 mapid = corpse->GetMapId(); float x = corpse->GetPositionX(); float y = corpse->GetPositionY(); float z = corpse->GetPositionZ(); uint32 corpsemapid = mapid; // if corpse at different map if (mapid != _player->GetMapId()) { // search entrance map for proper show entrance if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapid)) { if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0) { // if corpse map have entrance if (Map const* entranceMap = sMapMgr->CreateBaseMap(corpseMapEntry->entrance_map)) { mapid = corpseMapEntry->entrance_map; x = corpseMapEntry->entrance_x; y = corpseMapEntry->entrance_y; z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT); } } } } WorldPacket data(MSG_CORPSE_QUERY, 1+(6*4)); data << uint8(1); // corpse found data << int32(mapid); data << float(x); data << float(y); data << float(z); data << int32(corpsemapid); data << uint32(0); // unknown SendPacket(&data); }
void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) { DETAIL_LOG("WORLD: Received MSG_CORPSE_QUERY"); Corpse *corpse = GetPlayer()->GetCorpse(); if(!corpse) { WorldPacket data(MSG_CORPSE_QUERY, 1); data << uint8(0); // corpse not found SendPacket(&data); return; } uint32 corpsemapid = corpse->GetMapId(); float x = corpse->GetPositionX(); float y = corpse->GetPositionY(); float z = corpse->GetPositionZ(); int32 mapid = corpsemapid; // if corpse at different map if (corpsemapid != _player->GetMapId()) { // search entrance map for proper show entrance if (InstanceTemplate const* temp = sObjectMgr.GetInstanceTemplate(mapid)) { if (temp->ghostEntranceMap >= 0) { // if corpse map have entrance if(TerrainInfo const* entranceMap = sTerrainMgr.LoadTerrain(temp->ghostEntranceMap)) { mapid = temp->ghostEntranceMap; x = temp->ghostEntranceX; y = temp->ghostEntranceY; z = entranceMap->GetHeight(x, y, MAX_HEIGHT); } } } } WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4)); data << uint8(1); // corpse found data << int32(mapid); data << float(x); data << float(y); data << float(z); data << uint32(corpsemapid); SendPacket(&data); }
Corpse * ObjectAccessor::GetCorpse(WorldObject const &u, uint64 guid) { Corpse * tmp = HashMapHolder<Corpse>::Find(guid); if (!tmp) return NULL; if (tmp->GetMapId() != u.GetMapId()) return NULL; if (tmp->GetInstanceId() != u.GetInstanceId()) return NULL; return tmp; }
void WorldSession::HandleQueryCorpseLocation(WorldPackets::Query::QueryCorpseLocationFromClient& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUERY_CORPSE_LOCATION_FROM_CLIENT"); Corpse* corpse = GetPlayer()->GetCorpse(); if (!corpse) { WorldPackets::Query::CorpseLocation packet; packet.Valid = false; // corpse not found SendPacket(packet.Write()); return; } uint32 mapID = corpse->GetMapId(); float x = corpse->GetPositionX(); float y = corpse->GetPositionY(); float z = corpse->GetPositionZ(); uint32 corpseMapID = mapID; // if corpse at different map if (mapID != _player->GetMapId()) { // search entrance map for proper show entrance if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapID)) { if (corpseMapEntry->IsDungeon() && corpseMapEntry->CorpseMapID >= 0) { // if corpse map have entrance if (Map const* entranceMap = sMapMgr->CreateBaseMap(corpseMapEntry->CorpseMapID)) { mapID = corpseMapEntry->CorpseMapID; x = corpseMapEntry->CorpsePos.X; y = corpseMapEntry->CorpsePos.Y; z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT); } } } } WorldPackets::Query::CorpseLocation packet; packet.Valid = true; packet.MapID = corpseMapID; packet.ActualMapID = mapID; packet.Position = G3D::Vector3(x, y, z); packet.Transport = corpse->GetTransGUID(); SendPacket(packet.Write()); }
////////////////////////////////////////////////////////////// /// This function handles MSG_CORPSE_QUERY: ////////////////////////////////////////////////////////////// void WorldSession::HandleCorpseQueryOpcode(WorldPacket &recv_data) { CHECK_INWORLD_RETURN LOG_DETAIL("WORLD: Received MSG_CORPSE_QUERY"); Corpse *pCorpse; WorldPacket data(MSG_CORPSE_QUERY, 25); MapInfo *pMapinfo; pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetLowGUID()); if(pCorpse) { pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pMapinfo) { if(pMapinfo->type == INSTANCE_NULL || pMapinfo->type == INSTANCE_BATTLEGROUND) { data << uint8(0x01); //show ? data << pCorpse->GetMapId(); // mapid (that tombstones shown on) data << pCorpse->GetPositionX(); data << pCorpse->GetPositionY(); data << pCorpse->GetPositionZ(); data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) data << uint32(0); SendPacket(&data); } else { data << uint8(0x01); //show ? data << pMapinfo->repopmapid; // mapid (that tombstones shown on) data << pMapinfo->repopx; data << pMapinfo->repopy; data << pMapinfo->repopz; data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) data << uint32(0); SendPacket(&data); } } else { data << uint8(0x01); //show ? data << pCorpse->GetMapId(); // mapid (that tombstones shown on) data << pCorpse->GetPositionX(); data << pCorpse->GetPositionY(); data << pCorpse->GetPositionZ(); data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) data << uint32(0); SendPacket(&data); } } }
////////////////////////////////////////////////////////////// /// This function handles MSG_CORPSE_QUERY: ////////////////////////////////////////////////////////////// void WorldSession::HandleCorpseQueryOpcode(WorldPacket &recv_data) { OUT_DEBUG("WORLD: Received MSG_CORPSE_QUERY"); Corpse *pCorpse; //WorldPacket data(MSG_CORPSE_QUERY, 21); uint8 databuffer[100]; StackPacket data(MSG_CORPSE_QUERY, databuffer, 100); MapInfo *pMapinfo; pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetLowGUID()); if(pCorpse) { pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pMapinfo) { if(pMapinfo->type == INSTANCE_NULL || pMapinfo->type == INSTANCE_PVP) { data << uint8(0x01); //show ? data << pCorpse->GetMapId(); // mapid (that tombstones shown on) data << pCorpse->GetPositionX(); data << pCorpse->GetPositionY(); data << pCorpse->GetPositionZ(); data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) SendPacket(&data); } else { data << uint8(0x01); //show ? data << pMapinfo->repopmapid; // mapid (that tombstones shown on) data << pMapinfo->repopx; data << pMapinfo->repopy; data << pMapinfo->repopz; data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) data << uint32(0); // 3.2.2 SendPacket(&data); } } else { data.Initialize(MSG_CORPSE_QUERY); data << uint8(0x01); //show ? data << pCorpse->GetMapId(); // mapid (that tombstones shown on) data << pCorpse->GetPositionX(); data << pCorpse->GetPositionY(); data << pCorpse->GetPositionZ(); data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse) data << uint32(0); // 3.2.2 SendPacket(&data); } } }
void WorldSession::SendSpiritResurrect() { _player->ResurrectPlayer(0.5f, true); _player->DurabilityLossAll(0.25f,true); // get corpse nearest graveyard WorldSafeLocsEntry const *corpseGrave = NULL; Corpse *corpse = _player->GetCorpse(); if(corpse) corpseGrave = objmgr.GetClosestGraveYard( corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetMapId(), _player->GetTeam() ); // now can spawn bones _player->SpawnCorpseBones(); // teleport to nearest from corpse graveyard, if different from nearest to player ghost if(corpseGrave) { WorldSafeLocsEntry const *ghostGrave = objmgr.GetClosestGraveYard( _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeam() ); if(corpseGrave != ghostGrave) _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); // or update at original position else //ObjectAccessor::UpdateVisibilityForPlayer(_player); _player->SetToNotify(); } // or update at original position else //ObjectAccessor::UpdateVisibilityForPlayer(_player); _player->SetToNotify(); _player->SaveToDB(); }
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() { // 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( 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::SendSpiritResurrect() { _player->ResurrectPlayer(0.5f, true); _player->DurabilityLossAll(0.25f, true); // get corpse nearest graveyard WorldSafeLocsEntry const* corpseGrave = NULL; Corpse* corpse = _player->GetCorpse(); if (corpse) corpseGrave = sObjectMgr->GetClosestGraveyard(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetMapId(), _player->GetTeamId()); // now can spawn bones _player->SpawnCorpseBones(); // teleport to nearest from corpse graveyard, if different from nearest to player ghost if (corpseGrave) { WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveyard(_player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeamId()); if (corpseGrave != ghostGrave) _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); // or update at original position //else // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer } // or update at original position //else // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer }
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::HandleAreaTriggerOpcode(WorldPacket & recv_data) { CHECK_PACKET_SIZE(recv_data, 4); uint32 id = 0; WorldPacket data(80); AreaTrigger *pAreaTrigger = NULL; recv_data >> id; sLog.outDebug("AreaTrigger: %u", id); pAreaTrigger = sWorld.GetAreaTrigger(id); // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); // if in BG handle is triggers if(GetPlayer()->m_bgInBattleground && GetPlayer()->GetCurrentBattleground() != NULL) { GetPlayer()->GetCurrentBattleground()->HandleBattlegroundAreaTrigger(GetPlayer(), id); return; } if(pAreaTrigger && pAreaTrigger->Type == ATTYPE_BATTLEGROUND) { if(pAreaTrigger->Mapid == 489) // hack fix pAreaTrigger->Mapid = 2; else if(pAreaTrigger->Mapid == 529) pAreaTrigger->Mapid = 3; else if(pAreaTrigger->Mapid == 30) pAreaTrigger->Mapid = 1; WorldPacket *pkt = sBattlegroundMgr.BuildBattlegroundListPacket(GetPlayer()->GetGUID(), _player, pAreaTrigger->Mapid); SendPacket(pkt); delete pkt; return; } if(pAreaTrigger) { bool bFailedPre = false; std::string failed_reason; if(pAreaTrigger->required_level) { if(GetPlayer()->getLevel() < pAreaTrigger->required_level) { bFailedPre = true; if(failed_reason.size() > 0) failed_reason += ", and "; else failed_reason = "You must be "; // mm hacky char lvltext[30]; sprintf(lvltext, "at least level %d", pAreaTrigger->required_level); failed_reason += lvltext; } } if(bFailedPre) { failed_reason += " before you're allowed through here."; WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << failed_reason << uint8(0); SendPacket(&msg); sLog.outDebug("Player %s failed areatrigger prereq - %s", GetPlayer()->GetName(), failed_reason.c_str()); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(); //death system check. Corpse *pCorpse = NULL; CorpseData *pCorpseData = NULL; MapInfo *pMapinfo = NULL; pMapinfo = sWorld.GetMapInformation(pAreaTrigger->Mapid); if(pMapinfo && !pMapinfo->HasFlag(WMI_INSTANCE_ENABLED)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "This instance is currently unavailable." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } if(!GetPlayer()->isAlive()) { pCorpse = objmgr.GetCorpseByOwner(GetPlayer()); if(pCorpse) { pMapinfo = sWorld.GetMapInformation(pCorpse->GetMapId()); if(pMapinfo) { if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pMapinfo->type != INSTANCE_NONRAID && GetPlayer()->GetMapId() != pCorpse->GetMapId() && pCorpse->GetMapId() == pAreaTrigger->Mapid && !GetPlayer()->InGroup()) { GetPlayer()->ResurrectPlayer(); return; } else if(pMapinfo->type != INSTANCE_NONRAID) { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); return; } } } else { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(),GetPlayer()->GetMapId()); return; } } sWorldCreator.CheckInstanceForObject(static_cast<Object*>(_player), pMapinfo); _player->SaveEntryPoint(); _player->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { // Inn if (!GetPlayer()->m_isResting) GetPlayer()->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { _player->SaveEntryPoint(); _player->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_NULL: { MapInfo *pMapinfo = NULL; pMapinfo = sWorld.GetMapInformation(pAreaTrigger->Mapid); if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } } default:break; } } }
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; } }
void WorldSession::_HandleAreaTriggerOpcode(uint32 id) { sLog.outDebug("AreaTrigger: %u", id); WorldPacket data(80); AreaTrigger * pAreaTrigger = AreaTriggerStorage.LookupEntry(id); // Search quest log, find any exploration quests sQuestMgr.OnPlayerExploreArea(GetPlayer(),id); // if in BG handle is triggers if(GetPlayer()->m_bgInBattleground && GetPlayer()->GetCurrentBattleground() != NULL) { GetPlayer()->GetCurrentBattleground()->HandleBattlegroundAreaTrigger(GetPlayer(), id); return; } if(GetPermissionCount()) { sChatHandler.BlueSystemMessage(this, "[%sSystem%s] |rEntered areatrigger: %s%u.", MSG_COLOR_WHITE, MSG_COLOR_LIGHTBLUE, MSG_COLOR_SUBWHITE, id); } /* if we don't have an areatrigger, create one on the stack to use for gm scripts :p */ if(!pAreaTrigger) { AreaTrigger tmpTrigger; tmpTrigger.AreaTriggerID = id; ScriptSystem->OnActivateAreaTrigger(&tmpTrigger, _player); return; } /* script prerequsites */ if(ScriptSystem->OnActivateAreaTrigger(pAreaTrigger, _player) == false) return; if(pAreaTrigger->Type == ATTYPE_BATTLEGROUND) { if(pAreaTrigger->Mapid == 489) // hack fix pAreaTrigger->Mapid = 2; else if(pAreaTrigger->Mapid == 529) pAreaTrigger->Mapid = 3; else if(pAreaTrigger->Mapid == 30) pAreaTrigger->Mapid = 1; WorldPacket *pkt = sBattlegroundMgr.BuildBattlegroundListPacket(GetPlayer()->GetGUID(), _player, pAreaTrigger->Mapid); SendPacket(pkt); delete pkt; return; } bool bFailedPre = false; std::string failed_reason; if(pAreaTrigger->required_level) { if(GetPlayer()->getLevel() < pAreaTrigger->required_level) { bFailedPre = true; if(failed_reason.size() > 0) failed_reason += ", and "; else failed_reason = "You must be "; // mm hacky char lvltext[30]; snprintf(lvltext, 30, "at least level %d", (int)pAreaTrigger->required_level); failed_reason += lvltext; } } if(bFailedPre) { failed_reason += " before you're allowed through here."; WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << failed_reason << uint8(0); SendPacket(&msg); sLog.outDebug("Player %s failed areatrigger prereq - %s", GetPlayer()->GetName(), failed_reason.c_str()); return; } switch(pAreaTrigger->Type) { case ATTYPE_INSTANCE: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); //death system check. Corpse *pCorpse = NULL; // CorpseData *pCorpseData = NULL; MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && !pMapinfo->HasFlag(WMI_INSTANCE_ENABLED)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "This instance is currently unavailable." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->iInstanceType == MODE_HEROIC && pMapinfo->type != INSTANCE_NULL) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "Heroic mode is not available for this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && GetPlayer()->InGroup() && GetPlayer()->GetGroup()->GetGroupType() != GROUP_TYPE_RAID) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->type == INSTANCE_RAID && !GetPlayer()->InGroup()) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You need to be in a raid group to be able to enter this instance." << uint8(0) << uint8(0); SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_quest && !_player->HasFinishedQuest(pMapinfo->required_quest)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(pMapinfo && pMapinfo->required_item && !_player->GetItemInterface()->GetItemCount(pMapinfo->required_item, true)) { WorldPacket msg; msg.Initialize(SMSG_AREA_TRIGGER_MESSAGE); msg << uint32(0) << "You do not have the required attunement to enter this instance."; SendPacket(&msg); return; } if(!GetPlayer()->isAlive()) { pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetGUIDLow()); if(pCorpse) { pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId()); if(pMapinfo) { if(GetPlayer()->InGroup()) { MapMgr * groupinstance = sWorldCreator.GetInstanceByGroup(GetPlayer()->GetGroup(), GetPlayer(), pMapinfo); if (groupinstance) { if(groupinstance->GetPlayerCount() >= pMapinfo->playerlimit) { data.Initialize(SMSG_TRANSFER_ABORTED); data << uint32(INSTANCE_ABORT_FULL); _player->GetSession()->SendPacket(&data); GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); GetPlayer()->ResurrectPlayer(); return; } } } //if its a raid instance and corpse is inside and player is not in a group, ressurect if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pMapinfo->type != INSTANCE_NONRAID && pMapinfo->type != INSTANCE_MULTIMODE && GetPlayer()->GetMapId() != pCorpse->GetMapId() && pCorpse->GetMapId() == pAreaTrigger->Mapid && !GetPlayer()->InGroup()) { GetPlayer()->ResurrectPlayer(); return; } //if its a instance and player is trying to enter when corpse is on a diferent instance, repop back else if(pMapinfo->type != INSTANCE_NULL && pMapinfo->type != INSTANCE_PVP && pCorpse->GetMapId() != pAreaTrigger->Mapid) { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId()); return; } } } else { GetPlayer()->RepopAtGraveyard(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(),GetPlayer()->GetMapId()); return; } } bool result = sWorldCreator.CheckInstanceForObject(static_cast<Object*>(GetPlayer()), pMapinfo); if(result) { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } } }break; case ATTYPE_QUESTTRIGGER: { }break; case ATTYPE_INN: { // Inn if (!GetPlayer()->m_isResting) GetPlayer()->ApplyPlayerRestState(true); }break; case ATTYPE_TELEPORT: { if(GetPlayer()->GetPlayerStatus() != TRANSFER_PENDING) //only ports if player is out of pendings { GetPlayer()->SaveEntryPoint(pAreaTrigger->Mapid); GetPlayer()->SafeTeleport(pAreaTrigger->Mapid, 0, LocationVector(pAreaTrigger->x, pAreaTrigger->y, pAreaTrigger->z, pAreaTrigger->o)); } }break; case ATTYPE_NULL: { MapInfo *pMapinfo = NULL; pMapinfo = WorldMapInfoStorage.LookupEntry(pAreaTrigger->Mapid); if(pMapinfo && pMapinfo->HasFlag(WMI_INSTANCE_XPACK_01) && !HasFlag(ACCOUNT_FLAG_XPACK_01)) { WorldPacket msg; msg.Initialize(SMSG_BROADCAST_MSG); msg << uint32(3) << "You must have The Burning Crusade Expansion to access this content." << uint8(0); SendPacket(&msg); return; } } default:break; } }
Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia) { Corpse *corpse = GetCorpseForPlayerGUID(player_guid); if(!corpse) { //in fact this function is called from several places //even when player doesn't have a corpse, not an error //sLog.outError("Try remove corpse that not in map for GUID %ul", player_guid); return NULL; } DEBUG_LOG("Deleting Corpse and spawning bones."); // remove corpse from player_guid -> corpse map RemoveCorpse(corpse); // remove resurrectble corpse from grid object registry (loaded state checked into call) // do not load the map if it's not loaded Map *map = sMapMgr.FindMap(corpse->GetMapId(), corpse->GetInstanceId()); if(map) map->Remove(corpse,false); // remove corpse from DB corpse->DeleteFromDB(); Corpse *bones = NULL; // create the bones only if the map and the grid is loaded at the corpse's location // ignore bones creating option in case insignia if (map && (insignia || (map->IsBattleGround() ? sWorld.getConfig(CONFIG_BOOL_DEATH_BONES_BG) : sWorld.getConfig(CONFIG_BOOL_DEATH_BONES_WORLD))) && !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY())) { // Create bones, don't change Corpse bones = new Corpse; bones->Create(corpse->GetGUIDLow()); for (int i = 3; i < CORPSE_END; i++) // don't overwrite guid and object type bones->SetUInt32Value(i, corpse->GetUInt32Value(i)); bones->SetGrid(corpse->GetGrid()); // bones->m_time = m_time; // don't overwrite time // bones->m_inWorld = m_inWorld; // don't overwrite world state // bones->m_type = m_type; // don't overwrite type bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES); bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0); for (int i = 0; i < EQUIPMENT_SLOT_END; i++) { if(corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i)) bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0); } // add bones in grid store if grid loaded where corpse placed map->Add(bones); } // all references to the corpse should be removed at this point delete corpse; return bones; }
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 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)) { 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; // 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(); }