Esempio n. 1
0
void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket &recv_data)
{
	// empty opcode
	CBattleground *bg = _player->m_bg;
	if(!_player->IsInWorld() || !bg)
		return;

	if(bg->GetType() == BATTLEGROUND_WARSONG_GULCH)
	{
		uint32 count1 = 0;
		uint32 count2 = 0;

		Player *ap = objmgr.GetPlayer(((WarsongGulch*)bg)->GetAllianceFlagHolderGUID());
		if(ap) ++count2;

		Player *hp = objmgr.GetPlayer(((WarsongGulch*)bg)->GetHordeFlagHolderGUID());
		if(hp) ++count2;

		WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
		data << count1;
		data << count2;
		if(ap)
		{
			data << (uint64)ap->GetGUID();
			data << (float)ap->GetPositionX();
			data << (float)ap->GetPositionY();
		}
		if(hp)
		{
			data << (uint64)hp->GetGUID();
			data << (float)hp->GetPositionX();
			data << (float)hp->GetPositionY();
		}

		SendPacket(&data);
	}
	else if(bg->GetType() == BATTLEGROUND_EYE_OF_THE_STORM)
	{
		uint32 count1 = 0;
		uint32 count2 = 0;

		Player *ap = objmgr.GetPlayer(((EyeOfTheStorm*)bg)->GetFlagHolderGUID());
		if(ap) ++count2;

		WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2));
		data << count1;
		data << count2;
		if(ap)
		{
			data << (uint64)ap->GetGUID();
			data << (float)ap->GetPositionX();
			data << (float)ap->GetPositionY();
		}

		SendPacket(&data);
	}
}
Esempio n. 2
0
void CBattlegroundManager::EventQueueUpdate(bool forceStart)
{
    deque<uint32> tempPlayerVec[2];
    uint32 i, j, k;
    Player* plr;
    CBattleground* bg;
    list<uint32>::iterator it3, it4;
    map<uint32, CBattleground*>::iterator iitr;
    Arena* arena;
    int32 team;
    uint32 plrguid;
    uint32 factionMap[MAX_PLAYER_TEAMS];
    uint32 count;
    std::queue< uint32 > teams[MAX_PLAYER_TEAMS];

    m_queueLock.Acquire();
    m_instanceLock.Acquire();

    for (i = 0; i < BATTLEGROUND_NUM_TYPES; ++i)
    {
        for (j = 0; j < MAX_LEVEL_GROUP; ++j)
        {
            if (!m_queuedPlayers[i][j].size())
                continue;

            tempPlayerVec[0].clear();
            tempPlayerVec[1].clear();

            // We try to add the players who queued for a specific Bg/Arena instance to
            // the Bg/Arena where they queued to, and add the rest to another list 
            for (it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
            {
                it4 = it3++;
                plrguid = *it4;
                plr = objmgr.GetPlayer(plrguid);

                // Player has left the game or switched level group since queuing (by leveling for example) 
                if (!plr || GetLevelGrouping(plr->getLevel()) != j)
                {
                    m_queuedPlayers[i][j].erase(it4);
                    continue;
                }

                // queued to a specific instance id?
                if (plr->m_bgQueueInstanceId != 0)
                {
                    iitr = m_instances[i].find(plr->m_bgQueueInstanceId);
                    if (iitr == m_instances[i].end())
                    {
                        // queue no longer valid, since instance has closed since queuing 
                        plr->GetSession()->SystemMessage(plr->GetSession()->LocalizedWorldSrv(52), plr->m_bgQueueInstanceId);
                        plr->m_bgIsQueued = false;
                        plr->m_bgQueueType = 0;
                        plr->m_bgQueueInstanceId = 0;
                        m_queuedPlayers[i][j].erase(it4);
                        continue;
                    }

                    // can we join the specified Bg instance?
                    bg = iitr->second;
                    if (bg->CanPlayerJoin(plr, bg->GetType()))
                    {
                        bg->AddPlayer(plr, plr->GetTeam());
                        m_queuedPlayers[i][j].erase(it4);
                    }
                }
                else
                {
                    if (IS_ARENA(i))
                        tempPlayerVec[plr->GetTeam()].push_back(plrguid);
                    else if (!plr->HasAura(BG_DESERTER))
                        tempPlayerVec[plr->GetTeam()].push_back(plrguid);
                }
            }

            // Now that we have a list of players who didn't queue for a specific instance
            // try to add them to a Bg/Arena that is already under way 
            for (iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr)
            {
                if (iitr->second->HasEnded() || iitr->second->GetLevelGroup() != j)
                    continue;

                if (IS_ARENA(i))
                {
                    arena = TO< Arena* >(iitr->second);
                    if (arena->Rated())
                        continue;

                    factionMap[0] = arena->GetTeamFaction(0);
                    factionMap[1] = arena->GetTeamFaction(1);

                    team = arena->GetFreeTeam();
                    while ((team >= 0) && (tempPlayerVec[factionMap[team]].size() > 0))
                    {
                        plrguid = *tempPlayerVec[factionMap[team]].begin();
                        tempPlayerVec[factionMap[team]].pop_front();
                        plr = objmgr.GetPlayer(plrguid);
                        if (plr)
                        {
                            plr->m_bgTeam = team;
                            arena->AddPlayer(plr, team);
                            team = arena->GetFreeTeam();
                        }
                        ErasePlayerFromList(plrguid, &m_queuedPlayers[i][j]);
                    }
                }
                else
                {
                    bg = iitr->second;
                    int size = (int)min(tempPlayerVec[0].size(), tempPlayerVec[1].size());
                    for (int counter = 0; (counter < size) && (bg->IsFull() == false); counter++)
                    {
                        AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0);
                        AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1);
                    }

                    while (tempPlayerVec[0].size() > 0 && bg->HasFreeSlots(0, bg->GetType()))
                    {
                        AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0);
                    }
                    while (tempPlayerVec[1].size() > 0 && bg->HasFreeSlots(1, bg->GetType()))
                    {
                        AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1);
                    }
                }
            }

            // Now that that we added everyone we could to a running Bg/Arena
            // We shall see if we can start a new one! 
            if (IS_ARENA(i))
            {
                // enough players to start a round?
                uint32 minPlayers = BattlegroundManager.GetMinimumPlayers(i);
                if (!forceStart && ((tempPlayerVec[0].size() + tempPlayerVec[1].size()) < (minPlayers * 2)))
                    continue;

                if (CanCreateInstance(i, j))
                {
                    arena = TO< Arena* >(CreateInstance(i, j));
                    if (arena == NULL)
                    {
                        sLog.Error("BattlegroundMgr", "%s (%u): Couldn't create Arena Instance", __FILE__, __LINE__);
                        m_queueLock.Release();
                        m_instanceLock.Release();
                        return;
                    } // No alliance in the queue
                    if (tempPlayerVec[0].size() == 0)
                    {
                        count = GetMaximumPlayers(i) * 2;
                        while ((count > 0) && (tempPlayerVec[1].size() > 0))
                        {
                            if (teams[0].size() > teams[1].size())
                                teams[1].push(tempPlayerVec[1].front());
                            else
                                teams[0].push(tempPlayerVec[1].front());
                            tempPlayerVec[1].pop_front();
                            count--;
                        }
                    }
                    else // No horde in the queue
                        if (tempPlayerVec[1].size() == 0)
                        {
                            count = GetMaximumPlayers(i) * 2;
                            while ((count > 0) && (tempPlayerVec[0].size() > 0))
                            {
                                if (teams[0].size() > teams[1].size())
                                    teams[1].push(tempPlayerVec[0].front());
                                else
                                    teams[0].push(tempPlayerVec[0].front());
                                tempPlayerVec[0].pop_front();
                                count--;
                            }
                        }
                        else // There are both alliance and horde players in the queue
                        {
                            count = GetMaximumPlayers(i);
                            while ((count > 0) && (tempPlayerVec[0].size() > 0) && (tempPlayerVec[1].size() > 0))
                            {
                                teams[0].push(tempPlayerVec[0].front());
                                teams[1].push(tempPlayerVec[1].front());
                                tempPlayerVec[0].pop_front();
                                tempPlayerVec[1].pop_front();
                                count--;
                            }
                        }

                    // Now we just need to add the players to the Arena instance
                    while (teams[0].size() > 0)
                    {
                        for (uint32 team = 0; team < 2; team++)
                        {
                            plrguid = teams[team].front();
                            teams[team].pop();
                            plr = objmgr.GetPlayer(plrguid);
                            if (plr == NULL)
                                continue;

                            plr->m_bgTeam = team;
                            arena->AddPlayer(plr, plr->m_bgTeam);
                            // remove from the main queue (painful!)
                            ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
                        }
                    }
                }
            }
            else
            {
                uint32 minPlayers = BattlegroundManager.GetMinimumPlayers(i);
                if (forceStart || (tempPlayerVec[0].size() >= minPlayers && tempPlayerVec[1].size() >= minPlayers))
                {
                    if (CanCreateInstance(i, j))
                    {
                        bg = CreateInstance(i, j);
                        if (bg == NULL)
                        {
                            m_queueLock.Release();
                            m_instanceLock.Release();
                            return;
                        }

                        // push as many as possible in
                        if (forceStart)
                        {
                            for (k = 0; k < 2; ++k)
                            {
                                while (tempPlayerVec[k].size() && bg->HasFreeSlots(k, bg->GetType()))
                                {
                                    AddPlayerToBgTeam(bg, &tempPlayerVec[k], i, j, k);
                                }
                            }
                        }
                        else
                        {
                            int size = (int)min(tempPlayerVec[0].size(), tempPlayerVec[1].size());
                            for (int counter = 0; (counter < size) && (bg->IsFull() == false); counter++)
                            {
                                AddPlayerToBgTeam(bg, &tempPlayerVec[0], i, j, 0);
                                AddPlayerToBgTeam(bg, &tempPlayerVec[1], i, j, 1);
                            }
                        }
                    }
                }
            }
        }
    }

    /* Handle paired arena team joining */
    Group* group1, *group2;
    uint32 teamids[2] = { 0, 0 };
    uint32 avgRating[2] = { 0, 0 };
    uint32 n;
    list<uint32>::iterator itz;
    for (i = BATTLEGROUND_ARENA_2V2; i <= BATTLEGROUND_ARENA_5V5; ++i)
    {
        if (!forceStart && m_queuedGroups[i].size() < 2)      /* got enough to have an arena battle ;P */
        {
            continue;
        }

        for (j = 0; j < (uint32)m_queuedGroups[i].size(); j++)
        {
            group1 = group2 = NULL;
            n = RandomUInt((uint32)m_queuedGroups[i].size()) - 1;
            for (itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end() && n > 0; ++itz)
                --n;

            if (itz == m_queuedGroups[i].end())
                itz = m_queuedGroups[i].begin();

            if (itz == m_queuedGroups[i].end())
            {
                sLog.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__);
                m_queueLock.Release();
                m_instanceLock.Release();
                return;
            }

            group1 = objmgr.GetGroupById(*itz);
            if (group1 == NULL)
            {
                continue;
            }

            if (forceStart && m_queuedGroups[i].size() == 1)
            {
                if (CreateArenaType(i, group1, NULL) == -1) return;
                m_queuedGroups[i].remove(group1->GetID());
                continue;
            }

            teamids[0] = GetArenaGroupQInfo(group1, i, &avgRating[0]);

            list<uint32> possibleGroups;
            for (itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); ++itz)
            {
                group2 = objmgr.GetGroupById(*itz);
                if (group2)
                {
                    teamids[1] = GetArenaGroupQInfo(group2, i, &avgRating[1]);
                    uint32 delta = abs((int32)avgRating[0] - (int32)avgRating[1]);
                    if (teamids[0] != teamids[1] && delta <= sWorld.ArenaQueueDiff)
                    {
                        possibleGroups.push_back(group2->GetID());
                    }
                }
            }

            if (possibleGroups.size() > 0)
            {
                n = RandomUInt((uint32)possibleGroups.size()) - 1;
                for (itz = possibleGroups.begin(); itz != possibleGroups.end() && n > 0; ++itz)
                    --n;

                if (itz == possibleGroups.end())
                    itz = possibleGroups.begin();

                if (itz == possibleGroups.end())
                {
                    sLog.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__);
                    m_queueLock.Release();
                    m_instanceLock.Release();
                    return;
                }

                group2 = objmgr.GetGroupById(*itz);
                if (group2)
                {
                    if (CreateArenaType(i, group1, group2) == -1) return;
                    m_queuedGroups[i].remove(group1->GetID());
                    m_queuedGroups[i].remove(group2->GetID());
                }
            }
        }
    }

    m_queueLock.Release();
    m_instanceLock.Release();
}