/* * Copyright (C) 2008-2010 TrinityCore * Copyright (C) 2005-2009 MaNGOS * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "Common.h" #include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "World.h" #include "ObjectMgr.h" #include "TicketMgr.h" #include "Player.h" #include "AccountMgr.h" #include "Opcodes.h" #include "Chat.h" #include "Log.h" #include "MapManager.h" #include "ObjectAccessor.h" #include "Language.h" #include "CellImpl.h" #include "InstanceSaveMgr.h" #include "Util.h" #include "Group.h" #ifdef _DEBUG_VMAPS #include "VMapFactory.h" #endif bool ChatHandler::HandleNameAnnounceCommand(const char* args) { WorldPacket data; if (!*args) return false; sWorld.SendWorldText(LANG_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args); return true; } bool ChatHandler::HandleGMNameAnnounceCommand(const char* args) { WorldPacket data; if (!*args) return false; sWorld.SendGMText(LANG_GM_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args); return true; } // global announce bool ChatHandler::HandleAnnounceCommand(const char* args) { if (!*args) return false; char buff[2048]; sprintf(buff, GetTrinityString(LANG_SYSTEMMESSAGE), args); sWorld.SendServerMessage(SERVER_MSG_STRING, buff); return true; } // announce to logged in GMs bool ChatHandler::HandleGMAnnounceCommand(const char* args) { if (!*args) return false; sWorld.SendGMText(LANG_GM_BROADCAST,args); return true; } //notification player at the screen bool ChatHandler::HandleNotifyCommand(const char* args) { if (!*args) return false; std::string str = GetTrinityString(LANG_GLOBAL_NOTIFY); str += args; WorldPacket data(SMSG_NOTIFICATION, (str.size()+1)); data << str; sWorld.SendGlobalMessage(&data); return true; } //notification GM at the screen bool ChatHandler::HandleGMNotifyCommand(const char* args) { if (!*args) return false; std::string str = GetTrinityString(LANG_GM_NOTIFY); str += args; WorldPacket data(SMSG_NOTIFICATION, (str.size()+1)); data << str; sWorld.SendGlobalGMMessage(&data); return true; } bool ChatHandler::HandleGPSCommand(const char* args) { WorldObject *obj = NULL; if (*args) { uint64 guid = extractGuidFromLink((char*)args); if (guid) obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); if (!obj) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return false; } } else { obj = getSelectedUnit(); if (!obj) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } } CellPair cell_val = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); Cell cell(cell_val); uint32 zone_id, area_id; obj->GetZoneAndAreaId(zone_id,area_id); MapEntry const* mapEntry = sMapStore.LookupEntry(obj->GetMapId()); AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zone_id); AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(area_id); float zone_x = obj->GetPositionX(); float zone_y = obj->GetPositionY(); Map2ZoneCoordinates(zone_x,zone_y,zone_id); Map const *map = obj->GetMap(); float ground_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), MAX_HEIGHT); float floor_z = map->GetHeight(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ()); GridPair p = Trinity::ComputeGridPair(obj->GetPositionX(), obj->GetPositionY()); // 63? WHY? int gx = 63 - p.x_coord; int gy = 63 - p.y_coord; uint32 have_map = Map::ExistMap(obj->GetMapId(),gx,gy) ? 1 : 0; uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0; if(have_vmap) { if(map->IsOutdoors(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ())) PSendSysMessage("You are outdoors"); else PSendSysMessage("You are indoors"); } else PSendSysMessage("no VMAP available for area info"); PSendSysMessage(LANG_MAP_POSITION, obj->GetMapId(), (mapEntry ? mapEntry->name[GetSessionDbcLocale()] : ""), zone_id, (zoneEntry ? zoneEntry->area_name[GetSessionDbcLocale()] : ""), area_id, (areaEntry ? areaEntry->area_name[GetSessionDbcLocale()] : ""), obj->GetPhaseMask(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(), cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), zone_x, zone_y, ground_z, floor_z, have_map, have_vmap); sLog.outDebug("Player %s GPS call for %s '%s' (%s: %u):", m_session ? GetNameLink().c_str() : GetTrinityString(LANG_CONSOLE_COMMAND), (obj->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), obj->GetName(), (obj->GetTypeId() == TYPEID_PLAYER ? "GUID" : "Entry"), (obj->GetTypeId() == TYPEID_PLAYER ? obj->GetGUIDLow(): obj->GetEntry())); sLog.outDebug(GetTrinityString(LANG_MAP_POSITION), obj->GetMapId(), (mapEntry ? mapEntry->name[sWorld.GetDefaultDbcLocale()] : ""), zone_id, (zoneEntry ? zoneEntry->area_name[sWorld.GetDefaultDbcLocale()] : ""), area_id, (areaEntry ? areaEntry->area_name[sWorld.GetDefaultDbcLocale()] : ""), obj->GetPhaseMask(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(), cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), zone_x, zone_y, ground_z, floor_z, have_map, have_vmap); LiquidData liquid_status; ZLiquidStatus res = map->getLiquidStatus(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), MAP_ALL_LIQUIDS, &liquid_status); if (res) { PSendSysMessage(LANG_LIQUID_STATUS, liquid_status.level, liquid_status.depth_level, liquid_status.type, res); } return true; } //Summon Player bool ChatHandler::HandleSummonCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; Player* _player = m_session->GetPlayer(); if (target == _player || target_guid == _player->GetGUID()) { PSendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } if (target) { std::string nameLink = playerLink(target_name); // check online security if (HasLowerSecurity(target, 0)) return false; if (target->IsBeingTeleported()) { PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); SetSentErrorMessage(true); return false; } Map* pMap = m_session->GetPlayer()->GetMap(); if (pMap->IsBattlegroundOrArena()) { // only allow if gm mode is on if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,nameLink.c_str()); SetSentErrorMessage(true); return false; } // if both players are in different bgs else if (target->GetBattlegroundId() && m_session->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff // all's well, set bg id // when porting out from the bg, it will be reset to 0 target->SetBattlegroundId(m_session->GetPlayer()->GetBattlegroundId(), m_session->GetPlayer()->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!target->GetMap()->IsBattlegroundOrArena()) target->SetBattlegroundEntryPoint(); } else if (pMap->IsDungeon()) { Map* cMap = target->GetMap(); if (cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId()) target->UnbindInstance(pMap->GetInstanceId(), target->GetDungeonDifficulty(), true); // we are in instance, and can summon only player in our group with us as lead if (!m_session->GetPlayer()->GetGroup() || !target->GetGroup() || (target->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID())) // the last check is a bit excessive, but let it be, just in case { PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,nameLink.c_str()); SetSentErrorMessage(true); return false; } } PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),""); if (needReportToTarget(target)) ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, playerLink(_player->GetName()).c_str()); // stop flight if need if (target->isInFlight()) { target->GetMotionMaster()->MovementExpired(); target->CleanupAfterTaxiFlight(); } // save only in non-flight case else target->SaveRecallPosition(); // before GM float x,y,z; m_session->GetPlayer()->GetClosePoint(x,y,z,target->GetObjectSize()); target->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,target->GetOrientation()); target->SetPhaseMask(m_session->GetPlayer()->GetPhaseMask(), true); } else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetTrinityString(LANG_OFFLINE)); // in point where GM stay Player::SavePositionInDB(m_session->GetPlayer()->GetMapId(), m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY(), m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetOrientation(), m_session->GetPlayer()->GetZoneId(), target_guid); } return true; } //Teleport to Player bool ChatHandler::HandleAppearCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; Player* _player = m_session->GetPlayer(); if (target == _player || target_guid == _player->GetGUID()) { SendSysMessage(LANG_CANT_TELEPORT_SELF); SetSentErrorMessage(true); return false; } if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; std::string chrNameLink = playerLink(target_name); Map* cMap = target->GetMap(); if (cMap->IsBattlegroundOrArena()) { // only allow if gm mode is on if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chrNameLink.c_str()); SetSentErrorMessage(true); return false; } // if both players are in different bgs else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff // all's well, set bg id // when porting out from the bg, it will be reset to 0 _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!_player->GetMap()->IsBattlegroundOrArena()) _player->SetBattlegroundEntryPoint(); } else if (cMap->IsDungeon()) { // we have to go to instance, and can go to player only if: // 1) we are in his group (either as leader or as member) // 2) we are not bound to any group and have GM mode on if (_player->GetGroup()) { // we are in group, we can go only if we are in the player group if (_player->GetGroup() != target->GetGroup()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str()); SetSentErrorMessage(true); return false; } } else { // we are not in group, let's verify our GM mode if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM,chrNameLink.c_str()); SetSentErrorMessage(true); return false; } } // if the player or the player's group is bound to another instance // the player will not be bound to another one InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(cMap->IsRaid())); if (!pBind) { Group *group = _player->GetGroup(); // if no bind exists, create a solo bind InstanceGroupBind *gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind if (!gBind) if (InstanceSave *save = sInstanceSaveMgr.GetInstanceSave(target->GetInstanceId())) _player->BindToInstance(save, !save->CanReset()); } if (cMap->IsRaid()) _player->SetRaidDifficulty(target->GetRaidDifficulty()); else _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); } PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); // stop flight if need if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } // save only in non-flight case else _player->SaveRecallPosition(); // to point to see at target with same orientation float x,y,z; target->GetContactPoint(_player,x,y,z); _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); _player->SetPhaseMask(target->GetPhaseMask(), true); } else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); // to point where player stay (if loaded) float x,y,z,o; uint32 map; bool in_flight; if (!Player::LoadPositionFromDB(map,x,y,z,o,in_flight,target_guid)) return false; // stop flight if need if (_player->isInFlight()) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); } // save only in non-flight case else _player->SaveRecallPosition(); _player->TeleportTo(map, x, y, z,_player->GetOrientation()); } return true; } // Teleport player to last position bool ChatHandler::HandleRecallCommand(const char* args) { Player* target; if (!extractPlayerTarget((char*)args,&target)) return false; // check online security if (HasLowerSecurity(target, 0)) return false; if (target->IsBeingTeleported()) { PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(target).c_str()); SetSentErrorMessage(true); return false; } // stop flight if need if (target->isInFlight()) { target->GetMotionMaster()->MovementExpired(); target->CleanupAfterTaxiFlight(); } target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); return true; } //Enable On\OFF all taxi paths bool ChatHandler::HandleTaxiCheatCommand(const char* args) { if (!*args) { SendSysMessage(LANG_USE_BOL); SetSentErrorMessage(true); return false; } std::string argstr = (char*)args; Player *chr = getSelectedPlayer(); if (!chr) { chr=m_session->GetPlayer(); } // check online security else if (HasLowerSecurity(chr, 0)) return false; if (argstr == "on") { chr->SetTaxiCheater(true); PSendSysMessage(LANG_YOU_GIVE_TAXIS, GetNameLink(chr).c_str()); if (needReportToTarget(chr)) ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, GetNameLink().c_str()); return true; } if (argstr == "off") { chr->SetTaxiCheater(false); PSendSysMessage(LANG_YOU_REMOVE_TAXIS, GetNameLink(chr).c_str()); if (needReportToTarget(chr)) ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, GetNameLink().c_str()); return true; } SendSysMessage(LANG_USE_BOL); SetSentErrorMessage(true); return false; } bool ChatHandler::HandleLookupAreaCommand(const char* args) { if (!*args) return false; std::string namepart = args; std::wstring wnamepart; if (!Utf8toWStr (namepart,wnamepart)) return false; bool found = false; uint32 count = 0; uint32 maxResults = sWorld.getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS); // converting string that we try to find to lower case wstrToLower (wnamepart); // Search in AreaTable.dbc for (uint32 areaflag = 0; areaflag < sAreaStore.GetNumRows (); ++areaflag) { AreaTableEntry const *areaEntry = sAreaStore.LookupEntry (areaflag); if (areaEntry) { int loc = GetSessionDbcLocale (); std::string name = areaEntry->area_name[loc]; if (name.empty()) continue; if (!Utf8FitTo (name, wnamepart)) { loc = 0; for (; loc < TOTAL_LOCALES; ++loc) { if (loc == GetSessionDbcLocale ()) continue; name = areaEntry->area_name[loc]; if (name.empty ()) continue; if (Utf8FitTo (name, wnamepart)) break; } } if (loc < TOTAL_LOCALES) { if (maxResults && count++ == maxResults) { PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); return true; } // send area in "id - [name]" format std::ostringstream ss; if (m_session) ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << " " << localeNames[loc]<< "]|h|r"; else ss << areaEntry->ID << " - " << name << " " << localeNames[loc]; SendSysMessage (ss.str ().c_str()); if (!found) found = true; } } } if (!found) SendSysMessage (LANG_COMMAND_NOAREAFOUND); return true; } //Find tele in game_tele order by name bool ChatHandler::HandleLookupTeleCommand(const char * args) { if (!*args) { SendSysMessage(LANG_COMMAND_TELE_PARAMETER); SetSentErrorMessage(true); return false; } char const* str = strtok((char*)args, " "); if (!str) return false; std::string namepart = str; std::wstring wnamepart; if (!Utf8toWStr(namepart,wnamepart)) return false; // converting string that we try to find to lower case wstrToLower(wnamepart); std::ostringstream reply; uint32 count = 0; uint32 maxResults = sWorld.getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS); bool limitReached = false; GameTeleMap const & teleMap = sObjectMgr.GetGameTeleMap(); for (GameTeleMap::const_iterator itr = teleMap.begin(); itr != teleMap.end(); ++itr) { GameTele const* tele = &itr->second; if (tele->wnameLow.find(wnamepart) == std::wstring::npos) continue; if (maxResults && count++ == maxResults) { limitReached = true; break; } if (m_session) reply << " |cffffffff|Htele:" << itr->first << "|h[" << tele->name << "]|h|r\n"; else reply << " " << itr->first << " " << tele->name << "\n"; } if (reply.str().empty()) SendSysMessage(LANG_COMMAND_TELE_NOLOCATION); else PSendSysMessage(LANG_COMMAND_TELE_LOCATION,reply.str().c_str()); if (limitReached) PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); return true; } //Enable\Dissable accept whispers (for GM) bool ChatHandler::HandleWhispersCommand(const char* args) { if (!*args) { PSendSysMessage(LANG_COMMAND_WHISPERACCEPTING, m_session->GetPlayer()->isAcceptWhispers() ? GetTrinityString(LANG_ON) : GetTrinityString(LANG_OFF)); return true; } std::string argstr = (char*)args; // whisper on if (argstr == "on") { m_session->GetPlayer()->SetAcceptWhispers(true); SendSysMessage(LANG_COMMAND_WHISPERON); return true; } // whisper off if (argstr == "off") { m_session->GetPlayer()->SetAcceptWhispers(false); SendSysMessage(LANG_COMMAND_WHISPEROFF); return true; } SendSysMessage(LANG_USE_BOL); SetSentErrorMessage(true); return false; } //Save all players in the world bool ChatHandler::HandleSaveAllCommand(const char* /*args*/) { sObjectAccessor.SaveAllPlayers(); SendSysMessage(LANG_PLAYERS_SAVED); return true; } //Send mail by command bool ChatHandler::HandleSendMailCommand(const char* args) { // format: name "subject text" "mail text" Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name)) return false; char* tail1 = strtok(NULL, ""); if (!tail1) return false; char* msgSubject = extractQuotedArg(tail1); if (!msgSubject) return false; char* tail2 = strtok(NULL, ""); if (!tail2) return false; char* msgText = extractQuotedArg(tail2); if (!msgText) return false; // msgSubject, msgText isn't NUL after prev. check std::string subject = msgSubject; std::string text = msgText; // from console show not existed sender MailSender sender(MAIL_NORMAL,m_session ? m_session->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); //- TODO: Fix poor design SQLTransaction trans = CharacterDatabase.BeginTransaction(); MailDraft(subject, text) .SendMailTo(trans, MailReceiver(target,GUID_LOPART(target_guid)),sender); CharacterDatabase.CommitTransaction(trans); std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); return true; } //Summon group of player bool ChatHandler::HandleGroupSummonCommand(const char* args) { Player* target; if (!extractPlayerTarget((char*)args,&target)) return false; // check online security if (HasLowerSecurity(target, 0)) return false; Group *grp = target->GetGroup(); std::string nameLink = GetNameLink(target); if (!grp) { PSendSysMessage(LANG_NOT_IN_GROUP,nameLink.c_str()); SetSentErrorMessage(true); return false; } Map* gmMap = m_session->GetPlayer()->GetMap(); bool to_instance = gmMap->Instanceable(); // we are in instance, and can summon only player in our group with us as lead if (to_instance && ( !m_session->GetPlayer()->GetGroup() || (grp->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()))) // the last check is a bit excessive, but let it be, just in case { SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); SetSentErrorMessage(true); return false; } for (GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *pl = itr->getSource(); if (!pl || pl == m_session->GetPlayer() || !pl->GetSession()) continue; // check online security if (HasLowerSecurity(pl, 0)) return false; std::string plNameLink = GetNameLink(pl); if (pl->IsBeingTeleported() == true) { PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); SetSentErrorMessage(true); return false; } if (to_instance) { Map* plMap = pl->GetMap(); if (plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId()) { // cannot summon from instance to instance PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST,plNameLink.c_str()); SetSentErrorMessage(true); return false; } } PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(),""); if (needReportToTarget(pl)) ChatHandler(pl).PSendSysMessage(LANG_SUMMONED_BY, GetNameLink().c_str()); // stop flight if need if (pl->isInFlight()) { pl->GetMotionMaster()->MovementExpired(); pl->CleanupAfterTaxiFlight(); } // save only in non-flight case else pl->SaveRecallPosition(); // before GM float x,y,z; m_session->GetPlayer()->GetClosePoint(x,y,z,pl->GetObjectSize()); pl->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,pl->GetOrientation()); } return true; }