bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { Player* player = ObjectAccessor::FindPlayerInOrOutOfWorld(m_PlayerGuid); // player logged off, so he is no longer in queue if (!player) return true; Battleground* bg = sBattlegroundMgr->GetBattleground(m_BgInstanceGUID); // if battleground ended, do nothing if (!bg) return true; // check if still in queue for this battleground BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(m_BgTypeId, m_ArenaType); uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) { // confirm the player is invited to this instance id (he didn't requeue in the meanwhile) BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime)) { // send remaining time in queue WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType, TEAM_NEUTRAL, bg->isRated(), m_BgTypeId); player->GetSession()->SendPacket(&data); } } return true; }
/* this method is called when group is inserted, or player / group is removed from BG Queue - there is only one player's status changed, so we don't use while (true) cycles to invite whole queue it must be called after fully adding the members of a group to ensure group joining should be called from Battleground::RemovePlayer function in some cases */ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id, uint8 arenaType, bool isRated, uint32 arenaRating) { //if no players in queue - do nothing if (m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].empty()) return; // battleground with free slot for player should be always in the beggining of the queue // maybe it would be better to create bgfreeslotqueue for each bracket_id BGFreeSlotQueueContainer& bgQueues = sBattlegroundMgr->GetBGFreeSlotQueueStore(bgTypeId); for (BGFreeSlotQueueContainer::iterator itr = bgQueues.begin(); itr != bgQueues.end();) { Battleground* bg = *itr; ++itr; // DO NOT allow queue manager to invite new player to rated games if (!bg->isRated() && bg->GetTypeID() == bgTypeId && bg->GetBracketId() == bracket_id && bg->GetStatus() > STATUS_WAIT_QUEUE && bg->GetStatus() < STATUS_WAIT_LEAVE) { // clear selection pools m_SelectionPools[TEAM_ALLIANCE].Init(); m_SelectionPools[TEAM_HORDE].Init(); // call a function that does the job for us FillPlayersToBG(bg, bracket_id); // now everything is set, invite players for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_ALLIANCE].SelectedGroups.end(); ++citr) InviteGroupToBG((*citr), bg, (*citr)->Team); for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_HORDE].SelectedGroups.end(); ++citr) InviteGroupToBG((*citr), bg, (*citr)->Team); if (!bg->HasFreeSlots()) bg->RemoveFromBGFreeSlotQueue(); } } // finished iterating through the bgs with free slots, maybe we need to create a new bg Battleground* bg_template = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg_template) { sLog->outError(LOG_FILTER_BATTLEGROUND, "Battleground: Update: bg template not found for %u", bgTypeId); return; } PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketById(bg_template->GetMapId(), bracket_id); if (!bracketEntry) { sLog->outError(LOG_FILTER_BATTLEGROUND, "Battleground: Update: bg bracket entry not found for map %u bracket id %u", bg_template->GetMapId(), bracket_id); return; } // get the min. players per team, properly for larger arenas as well. (must have full teams for arena matches!) uint32 MinPlayersPerTeam = bg_template->GetMinPlayersPerTeam(); uint32 MaxPlayersPerTeam = bg_template->GetMaxPlayersPerTeam(); if (bg_template->isArena()) { MaxPlayersPerTeam = arenaType; MinPlayersPerTeam = sBattlegroundMgr->isArenaTesting() ? 1 : arenaType; } else if (sBattlegroundMgr->isTesting()) MinPlayersPerTeam = 1; m_SelectionPools[TEAM_ALLIANCE].Init(); m_SelectionPools[TEAM_HORDE].Init(); if (bg_template->isBattleground()) { if (CheckPremadeMatch(bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam)) { // create new battleground Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, 0, false); if (!bg2) { sLog->outError(LOG_FILTER_BATTLEGROUND, "BattlegroundQueue::Update - Cannot create battleground: %u", bgTypeId); return; } // invite those selection pools for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr) InviteGroupToBG((*citr), bg2, (*citr)->Team); bg2->StartBattleground(); //clear structures m_SelectionPools[TEAM_ALLIANCE].Init(); m_SelectionPools[TEAM_HORDE].Init(); } } // now check if there are in queues enough players to start new game of (normal battleground, or non-rated arena) if (!isRated) { // if there are enough players in pools, start new battleground or non rated arena if (CheckNormalMatch(bg_template, bracket_id, MinPlayersPerTeam, MaxPlayersPerTeam) || (bg_template->isArena() && CheckSkirmishForSameFaction(bracket_id, MinPlayersPerTeam))) { // we successfully created a pool Battleground* bg2 = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, false); if (!bg2) { sLog->outError(LOG_FILTER_BATTLEGROUND, "BattlegroundQueue::Update - Cannot create battleground: %u", bgTypeId); return; } // invite those selection pools for (uint32 i = 0; i < BG_TEAMS_COUNT; i++) for (GroupsQueueType::const_iterator citr = m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr) InviteGroupToBG((*citr), bg2, (*citr)->Team); // start bg bg2->StartBattleground(); } } else if (bg_template->isArena()) { // found out the minimum and maximum ratings the newly added team should battle against // arenaRating is the rating of the latest joined team, or 0 // 0 is on (automatic update call) and we must set it to team's with longest wait time if (!arenaRating) { GroupQueueInfo* front1 = NULL; GroupQueueInfo* front2 = NULL; if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty()) { front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front(); arenaRating = front1->ArenaMatchmakerRating; } if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].empty()) { front2 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].front(); arenaRating = front2->ArenaMatchmakerRating; } if (front1 && front2) { if (front1->JoinTime < front2->JoinTime) arenaRating = front1->ArenaMatchmakerRating; } else if (!front1 && !front2) return; //queues are empty } //set rating range uint32 arenaMinRating = (arenaRating <= sBattlegroundMgr->GetMaxRatingDifference()) ? 0 : arenaRating - sBattlegroundMgr->GetMaxRatingDifference(); uint32 arenaMaxRating = arenaRating + sBattlegroundMgr->GetMaxRatingDifference(); // if max rating difference is set and the time past since server startup is greater than the rating discard time // (after what time the ratings aren't taken into account when making teams) then // the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account // else leave the discard time on 0, this way all ratings will be discarded uint32 discardTime = getMSTime() - sBattlegroundMgr->GetRatingDiscardTimer(); // we need to find 2 teams which will play next game GroupsQueueType::iterator itr_teams[BG_TEAMS_COUNT]; uint8 found = 0; uint8 team = 0; for (uint8 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++) { // take the group that joined first GroupsQueueType::iterator itr2 = m_QueuedGroups[bracket_id][i].begin(); for (; itr2 != m_QueuedGroups[bracket_id][i].end(); ++itr2) { // if group match conditions, then add it to pool if (!(*itr2)->IsInvitedToBGInstanceGUID && (((*itr2)->ArenaMatchmakerRating >= arenaMinRating && (*itr2)->ArenaMatchmakerRating <= arenaMaxRating) || (*itr2)->JoinTime < discardTime)) { itr_teams[found++] = itr2; team = i; break; } } } if (!found) return; if (found == 1) { for (GroupsQueueType::iterator itr3 = itr_teams[0]; itr3 != m_QueuedGroups[bracket_id][team].end(); ++itr3) { if (!(*itr3)->IsInvitedToBGInstanceGUID && (((*itr3)->ArenaMatchmakerRating >= arenaMinRating && (*itr3)->ArenaMatchmakerRating <= arenaMaxRating) || (*itr3)->JoinTime < discardTime) && (*itr_teams[0])->ArenaTeamId != (*itr3)->ArenaTeamId) { itr_teams[found++] = itr3; break; } } } //if we have 2 teams, then start new arena and invite players! if (found == 2) { GroupQueueInfo* aTeam = *itr_teams[TEAM_ALLIANCE]; GroupQueueInfo* hTeam = *itr_teams[TEAM_HORDE]; Battleground* arena = sBattlegroundMgr->CreateNewBattleground(bgTypeId, bracketEntry, arenaType, true); if (!arena) { sLog->outError(LOG_FILTER_BATTLEGROUND, "BattlegroundQueue::Update couldn't create arena instance for rated arena match!"); return; } aTeam->OpponentsTeamRating = hTeam->ArenaTeamRating; hTeam->OpponentsTeamRating = aTeam->ArenaTeamRating; aTeam->OpponentsMatchmakerRating = hTeam->ArenaMatchmakerRating; hTeam->OpponentsMatchmakerRating = aTeam->ArenaMatchmakerRating; sLog->outDebug(LOG_FILTER_BATTLEGROUND, "setting oposite teamrating for team %u to %u", aTeam->ArenaTeamId, aTeam->OpponentsTeamRating); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "setting oposite teamrating for team %u to %u", hTeam->ArenaTeamId, hTeam->OpponentsTeamRating); // now we must move team if we changed its faction to another faction queue, because then we will spam log by errors in Queue::RemovePlayer if (aTeam->Team != ALLIANCE) { m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].push_front(aTeam); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].erase(itr_teams[TEAM_ALLIANCE]); } if (hTeam->Team != HORDE) { m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_HORDE].push_front(hTeam); m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_teams[TEAM_HORDE]); } arena->SetArenaMatchmakerRating(ALLIANCE, aTeam->ArenaMatchmakerRating); arena->SetArenaMatchmakerRating( HORDE, hTeam->ArenaMatchmakerRating); InviteGroupToBG(aTeam, arena, ALLIANCE); InviteGroupToBG(hTeam, arena, HORDE); sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Starting rated arena match!"); arena->StartBattleground(); } } }
static bool HandleSpectateCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* player = handler->GetSession()->GetPlayer(); if (target == player || target_guid == player->GetGUID()) { handler->PSendSysMessage("Вы не можете смотреть на себя."); handler->SetSentErrorMessage(true); return false; } if (player->IsInCombat()) { handler->PSendSysMessage("Вы находитесь в Бою."); handler->SetSentErrorMessage(true); return false; } if (!target) { handler->PSendSysMessage("Цель не существует."); handler->SetSentErrorMessage(true); return false; } if (player->IsMounted()) { handler->PSendSysMessage("Не можете смотреть сидя верхом."); handler->SetSentErrorMessage(true); return false; } if (target && (target->HasAura(ARENA_PREPARATION) || target->HasAura(ARENA_PREPARATION_2))) { handler->PSendSysMessage("Не могу этого сделать. Арена не началась."); handler->SetSentErrorMessage(true); return false; } if (player->GetPet()) { handler->PSendSysMessage("Вы должны скрыть своего питомца."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattlegroundOrArena() && !player->isSpectator()) { handler->PSendSysMessage("Вы уже находитесь на поле битвы или арене."); handler->SetSentErrorMessage(true); return false; } Map* map = target->GetMap(); if (!map->IsBattleArena()) { handler->PSendSysMessage("Игрок не на арене."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattleground()) { handler->PSendSysMessage("Не могу сделать это, в то время как вы находитесь на поле боя."); handler->SetSentErrorMessage(true); return false; } // 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(); if (target->isSpectator()) { handler->PSendSysMessage("Не могу сделать этого. Ваша цель - зритель."); handler->SetSentErrorMessage(true); return false; } // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // search for two teams Battleground *bGround = target->GetBattleground(); if (bGround->isRated()) { uint32 slot = bGround->GetArenaType() - 2; if (bGround->GetArenaType() > 3) slot = 2; uint32 firstTeamID = target->GetArenaTeamId(slot); uint32 secondTeamID = 0; Player *firstTeamMember = target; Player *secondTeamMember = NULL; for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr) if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first)) { if (tmpPlayer->isSpectator()) continue; uint32 tmpID = tmpPlayer->GetArenaTeamId(slot); if (tmpID != firstTeamID && tmpID > 0) { secondTeamID = tmpID; secondTeamMember = tmpPlayer; break; } } if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember) { ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID); ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID); if (firstTeam && secondTeam) { handler->PSendSysMessage("Вы вошли на Арену."); handler->PSendSysMessage("Команды:"); handler->PSendSysMessage("%s - %s", firstTeam->GetName().c_str(), secondTeam->GetName().c_str()); handler->PSendSysMessage("%u(%u) - %u(%u)", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()), secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup())); } } } // 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); player->SetSpectate(true); target->GetBattleground()->AddSpectator(player->GetGUID()); return true; }
static bool HandleSpectateCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* player = handler->GetSession()->GetPlayer(); if (target == player || target_guid == player->GetGUID()) { handler->PSendSysMessage("你不能观察你自己."); handler->SetSentErrorMessage(true); return false; } if (player->IsInCombat()) { handler->PSendSysMessage("你在战斗状态."); handler->SetSentErrorMessage(true); return false; } if (!target) { handler->PSendSysMessage("目标不在线或不存在."); handler->SetSentErrorMessage(true); return false; } if (player->GetPet()) { handler->PSendSysMessage("你必须先解散你的宠物."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattlegroundOrArena() && !player->IsSpectator()) { handler->PSendSysMessage("你已经在战场或者竞技场了."); handler->SetSentErrorMessage(true); return false; } Map* cMap = target->GetMap(); if (!cMap->IsBattleArena()) { handler->PSendSysMessage("玩家还不在竞技场里."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattleground()) { handler->PSendSysMessage("你在战场里不能同时观察."); handler->SetSentErrorMessage(true); return false; } if (target->HasAura(32728) || target->HasAura(32727)) { handler->PSendSysMessage("你还不能观察,竞技场还没有开始."); handler->SetSentErrorMessage(true); return false; } if (target->IsSpectator()) { handler->PSendSysMessage("不能进入,目标在观察状态."); handler->SetSentErrorMessage(true); return false; } if (player->IsMounted()) { handler->PSendSysMessage("不能在有坐骑的情况下观察."); handler->SetSentErrorMessage(true); return false; } // 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(); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // search for two teams Battleground *bGround = target->GetBattleground(); if (bGround->isRated()) { uint32 slot = bGround->GetArenaType() - 2; if (bGround->GetArenaType() > 3) slot = 2; uint32 firstTeamID = target->GetArenaTeamId(slot); uint32 secondTeamID = 0; Player *firstTeamMember = target; Player *secondTeamMember = NULL; for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr) if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first)) { if (tmpPlayer->IsSpectator()) continue; uint32 tmpID = tmpPlayer->GetArenaTeamId(slot); if (tmpID != firstTeamID && tmpID > 0) { secondTeamID = tmpID; secondTeamMember = tmpPlayer; break; } } if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember) { ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID); ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID); if (firstTeam && secondTeam) { handler->PSendSysMessage("你进入了竞技场积分赛."); handler->PSendSysMessage("队伍:"); handler->PSendSysMessage("|cFFffffff%s|r vs |cFFffffff%s|r", firstTeam->GetName().c_str(), secondTeam->GetName().c_str()); handler->PSendSysMessage("|cFFffffff%u(%u)|r -- |cFFffffff%u(%u)|r", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()), secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup())); } } } // 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); player->SetSpectate(true); target->GetBattleground()->AddSpectator(player->GetGUID()); return true; }
static bool HandleSpectateCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* player = handler->GetSession()->GetPlayer(); if (target == player || target_guid == player->GetGUID()) { handler->PSendSysMessage("You can't spectate yourself."); handler->SetSentErrorMessage(true); return false; } if (player->IsInCombat()) { handler->PSendSysMessage("You are in combat."); handler->SetSentErrorMessage(true); return false; } if (!target) { handler->PSendSysMessage("Target is not online or does not exist."); handler->SetSentErrorMessage(true); return false; } if (player->GetPet()) { handler->PSendSysMessage("You must hide your pet."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattlegroundOrArena() && !player->IsSpectator()) { handler->PSendSysMessage("You are already in a battleground or arena."); handler->SetSentErrorMessage(true); return false; } Map* cMap = target->GetMap(); if (!cMap->IsBattleArena()) { handler->PSendSysMessage("Player is not in an Arena match."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattleground()) { handler->PSendSysMessage("You can't do that while in a battleground."); handler->SetSentErrorMessage(true); return false; } if (target->HasAura(32728) || target->HasAura(32727)) { handler->PSendSysMessage("You can't do that. The Arena match didn't start yet."); handler->SetSentErrorMessage(true); return false; } if (target->IsSpectator()) { handler->PSendSysMessage("You can't do that. Your target is a spectator."); handler->SetSentErrorMessage(true); return false; } if (player->IsMounted()) { handler->PSendSysMessage("Cannot Spectate while mounted."); handler->SetSentErrorMessage(true); return false; } // 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(); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // search for two teams Battleground *bGround = target->GetBattleground(); if (bGround->isRated()) { uint32 slot = bGround->GetArenaType() - 2; if (bGround->GetArenaType() > 3) slot = 2; uint32 firstTeamID = target->GetArenaTeamId(slot); uint32 secondTeamID = 0; Player *firstTeamMember = target; Player *secondTeamMember = NULL; for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr) if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first)) { if (tmpPlayer->IsSpectator()) continue; uint32 tmpID = tmpPlayer->GetArenaTeamId(slot); if (tmpID != firstTeamID && tmpID > 0) { secondTeamID = tmpID; secondTeamMember = tmpPlayer; break; } } if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember) { ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID); ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID); if (firstTeam && secondTeam) { handler->PSendSysMessage("You entered a Rated Arena."); handler->PSendSysMessage("Teams:"); handler->PSendSysMessage("|cFFffffff%s|r vs |cFFffffff%s|r", firstTeam->GetName().c_str(), secondTeam->GetName().c_str()); handler->PSendSysMessage("|cFFffffff%u(%u)|r -- |cFFffffff%u(%u)|r", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()), secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup())); } } } // 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); player->SetSpectate(true); target->GetBattleground()->AddSpectator(player->GetGUID()); return true; }
void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) { // requested at login and on map change // send status for current queues and current bg WorldPacket data; // for current bg send STATUS_IN_PROGRESS if (Battleground* bg = _player->GetBattleground()) if (bg->GetPlayers().count(_player->GetGUID())) { sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player->GetCurrentBattlegroundQueueSlot(), STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), bg->GetArenaType(), _player->GetBgTeamId()); SendPacket(&data); } // for queued bgs send STATUS_WAIT_JOIN or STATUS_WAIT_QUEUE for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { // check if in queue BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i); if (!bgQueueTypeId) continue; // get group info from queue BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); GroupQueueInfo ginfo; if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) continue; BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId); // if invited - send STATUS_WAIT_JOIN if (ginfo.IsInvitedToBGInstanceGUID) { Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID); if (!bg) continue; uint32 remainingTime = (World::GetGameTimeMS() < ginfo.RemoveInviteTime ? getMSTimeDiff(World::GetGameTimeMS(), ginfo.RemoveInviteTime) : 1); sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, ginfo.ArenaType, TEAM_NEUTRAL, bg->isRated(), ginfo.BgTypeId); SendPacket(&data); } // if not invited - send STATUS_WAIT_QUEUE else { Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bgt) continue; // expected bracket entry PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bgt->GetMapId(), _player->getLevel()); if (!bracketEntry) continue; uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(&ginfo); sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, i, STATUS_WAIT_QUEUE, avgWaitTime, getMSTimeDiff(ginfo.JoinTime, World::GetGameTimeMS()), ginfo.ArenaType, TEAM_NEUTRAL, ginfo.IsRated); SendPacket(&data); } } }