예제 #1
0
void CBattlegroundManager::RemovePlayerFromQueues(Player * plr)
{
	m_queueLock.Acquire();

	ASSERT(plr->m_bgQueueType < BATTLEGROUND_NUM_TYPES);
	uint32 lgroup = GetLevelGrouping(plr->getLevel());
	list<uint32>::iterator itr = m_queuedPlayers[plr->m_bgQueueType][lgroup].begin();
	
	while(itr != m_queuedPlayers[plr->m_bgQueueType][lgroup].end())
	{
		if((*itr) == plr->GetLowGUID())
		{
			Log.Debug("BattlegroundManager", "Removing player %u from queue instance %u type %u", plr->GetLowGUID(), plr->m_bgQueueInstanceId, plr->m_bgQueueType);
			m_queuedPlayers[plr->m_bgQueueType][lgroup].erase(itr);
			break;
		}

		++itr;
	}

	plr->m_bgIsQueued = false;
	plr->m_bgTeam=plr->GetTeam();
	plr->m_pendingBattleground=0;
	SendBattlefieldStatus(plr,0,0,0,0,0,0);
    m_queueLock.Release();
}
예제 #2
0
void CBattlegroundManager::HandleBattlegroundListPacket(WorldSession * m_session, uint32 BattlegroundType)
{
	if( BattlegroundType >= BATTLEGROUND_NUM_TYPES )
		return;

	if(BattlegroundType == BATTLEGROUND_ARENA_2V2 || BattlegroundType == BATTLEGROUND_ARENA_3V3 || BattlegroundType == BATTLEGROUND_ARENA_5V5)
	{
		WorldPacket data(SMSG_BATTLEFIELD_LIST, 17);
		data << m_session->GetPlayer()->GetGUID() << uint32(6) << uint32(0xC) << uint8(0);
		m_session->SendPacket(&data);
		return;
	}

	uint32 LevelGroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
	uint32 Count = 0;
	WorldPacket data(SMSG_BATTLEFIELD_LIST, 200);
	data << m_session->GetPlayer()->GetGUID();
	data << BattlegroundType;
	data << uint8(2);
	data << uint32(0);		// Count

	/* Append the battlegrounds */
	m_instanceLock.Acquire();
	for(map<uint32, CBattleground*>::iterator itr = m_instances[BattlegroundType].begin(); itr != m_instances[BattlegroundType].end(); ++itr)
	{
        if( itr->second->GetLevelGroup() == LevelGroup && itr->second->CanPlayerJoin(m_session->GetPlayer()) && !itr->second->HasEnded() )
		{
			data << itr->first;
			++Count;
		}
	}
	m_instanceLock.Release();
	*(uint32*)&data.contents()[13] = Count;
	m_session->SendPacket(&data);
}
예제 #3
0
void CBattlegroundManager::HandleBattlegroundJoin(WorldSession * m_session, WorldPacket & pck)
{
	uint64 guid;
	uint32 pguid = m_session->GetPlayer()->GetLowGUID();
	uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
	uint32 bgtype;
	uint32 instance;

	pck >> guid >> bgtype >> instance;

	if ( ! guid )
		return; //crash fix. /script JoinBattlefield(0,1); ;s

	if(bgtype >= BATTLEGROUND_NUM_TYPES || guid == 0 )
		return;		// cheater!

	/* Check the instance id */
	if(instance)
	{
		/* We haven't picked the first instance. This means we've specified an instance to join. */
		m_instanceLock.Acquire();
		map<uint32, CBattleground*>::iterator itr = m_instances[bgtype].find(instance);

		if(itr == m_instances[bgtype].end())
		{
			sChatHandler.SystemMessage(m_session, "You have tried to join an invalid instance id.");
			m_instanceLock.Release();
			return;
		}

		m_instanceLock.Release();
	}
    
	/* Queue him! */
	m_queueLock.Acquire();
	m_queuedPlayers[bgtype][lgroup].push_back(pguid);
	Log.Success("BattlegroundManager", "Player %u is now in battleground queue for instance %u", m_session->GetPlayer()->GetLowGUID(), instance );

	/* send the battleground status packet */
	SendBattlefieldStatus(m_session->GetPlayer(), 1, bgtype, instance, 0, BGMapIds[bgtype],0);
	m_session->GetPlayer()->m_bgIsQueued = true;
	m_session->GetPlayer()->m_bgQueueInstanceId = instance;
	m_session->GetPlayer()->m_bgQueueType = bgtype;

	/* Set battleground entry point */
	m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
	m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
	m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
	m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
	m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID();

	m_queueLock.Release();

	/* We will get updated next few seconds =) */
}
예제 #4
0
void CBattlegroundManager::RemovePlayerFromQueues(Player* plr)
{
    m_queueLock.Acquire();

    ARCEMU_ASSERT(plr->m_bgQueueType < BATTLEGROUND_NUM_TYPES);

    sEventMgr.RemoveEvents(plr, EVENT_BATTLEGROUND_QUEUE_UPDATE);

    uint32 lgroup = GetLevelGrouping(plr->getLevel());
    list<uint32>::iterator itr;

    itr = m_queuedPlayers[plr->m_bgQueueType][lgroup].begin();
    while (itr != m_queuedPlayers[plr->m_bgQueueType][lgroup].end())
    {
        if ((*itr) == plr->GetLowGUID())
        {
            Log.Debug("BattlegroundManager", "Removing player %u from queue instance %u type %u", plr->GetLowGUID(), plr->m_bgQueueInstanceId, plr->m_bgQueueType);
            m_queuedPlayers[plr->m_bgQueueType][lgroup].erase(itr);
            break;
        }

        ++itr;
    }

    plr->m_bgIsQueued = false;
    plr->m_bgTeam = plr->GetTeam();
    plr->m_pendingBattleground = NULL;
    SendBattlefieldStatus(plr, BGSTATUS_NOFLAGS, 0, 0, 0, 0, 0);
    m_queueLock.Release();

    Group* group;
    group = plr->GetGroup();
    if (group)  //if da n****s in a group, boot dis bitch ass' group outa da q
    {
        Log.Debug("BattlegroundManager", "Player %u removed whilst in a group. Removing players group %u from queue", plr->GetLowGUID(), group->GetID());
        RemoveGroupFromQueues(group);
    }
}
예제 #5
0
void CBattlegroundManager::EventQueueUpdate()
{
	deque<Player*> tempPlayerVec[2];
	uint32 i,j,k;
	Player * plr;
	CBattleground * bg;
	list<uint32>::iterator it3, it4;
	//vector<Player*>::iterator it6;
	map<uint32, CBattleground*>::iterator iitr;
	Arena * arena;
	int32 team;
	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();

			for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
			{
				it4 = it3++;
                plr = objmgr.GetPlayer(*it4);
				
				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
						plr->GetSession()->SystemMessage("Your queue on battleground instance id %u is no longer valid. Reason: Instance Deleted.", plr->m_bgQueueInstanceId);
						plr->m_bgIsQueued = false;
						plr->m_bgQueueType = 0;
						plr->m_bgQueueInstanceId = 0;
						m_queuedPlayers[i][j].erase(it4);
					}

					// can we join?
					bg = iitr->second;
					if(bg->CanPlayerJoin(plr))
					{
						bg->AddPlayer(plr, plr->GetTeam());
						m_queuedPlayers[i][j].erase(it4);
					}
				}
				else
				{
					if(IS_ARENA(i))
						tempPlayerVec[0].push_back(plr);
					else
						tempPlayerVec[plr->GetTeam()].push_back(plr);
				}
			}

			// try to join existing instances
			for(iitr = m_instances[i].begin(); iitr != m_instances[i].end(); ++iitr)
			{
				if( iitr->second->HasEnded() )
					continue;

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

					team = arena->GetFreeTeam();
					while(team >= 0 && tempPlayerVec[0].size())
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();
						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						team = arena->GetFreeTeam();
					}
				}
				else
				{
					bg = iitr->second;
					for(k = 0; k < 2; ++k)
					{
						while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
						{
							plr = *tempPlayerVec[k].begin();
							tempPlayerVec[k].pop_front();
							bg->AddPlayer(plr, plr->GetTeam());
							ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						}
					}
				}
			}
			
			if(IS_ARENA(i))
			{
				// enough players to start a round?
				if(tempPlayerVec[0].size() < BGMinimumPlayers[i])
					continue;

				if(CanCreateInstance(i,j))
				{
					arena = ((Arena*)CreateInstance(i, j));
					if ( arena == NULL )
						{
							m_queueLock.Release();
							m_instanceLock.Release();
							return;
						}
					team = arena->GetFreeTeam();
					while(!arena->IsFull() && tempPlayerVec[0].size() && team >= 0)
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();

						arena->AddPlayer(plr, team);
						team = arena->GetFreeTeam();

						// remove from the main queue (painful!)
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
					}
				}
			}
			else
			{
#ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG
				if(tempPlayerVec[0].size() >= 1 ||
					tempPlayerVec[1].size() >= 1)
#else
				if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] &&
					tempPlayerVec[1].size() >= BGMinimumPlayers[i])
#endif
				{
					if(CanCreateInstance(i,j))
					{
						bg = CreateInstance(i,j);
						//ASSERT(bg);
						if ( bg == NULL )
						{
							m_queueLock.Release();
							m_instanceLock.Release();
							return;
						}
						// push as many as possible in
						for(k = 0; k < 2; ++k)
						{
							while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
							{
								plr = *tempPlayerVec[k].begin();
								tempPlayerVec[k].pop_front();
								bg->AddPlayer(plr, k);
								ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
							}
						}
					}
				}
			}
		}
	}

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

			group1 = group2 = NULL;
			while(group1 == 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())
				{
					Log.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__);
					m_queueLock.Release();
					m_instanceLock.Release();
					return;
				}

				group1 = objmgr.GetGroupById(*itz);
				m_queuedGroups[i].erase(itz);
			}

			while(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())
				{
					Log.Error("BattlegroundMgr", "Internal error at %s:%u", __FILE__, __LINE__);
					m_queueLock.Release();
					m_instanceLock.Release();
					return;
				}

				group2 = objmgr.GetGroupById(*itz);
				m_queuedGroups[i].erase(itz);
			}

			Arena * ar = ((Arena*)CreateInstance(i,LEVEL_GROUP_70));
			GroupMembersSet::iterator itx;
			ar->rated_match=true;

			for(itx = group1->GetSubGroup(0)->GetGroupMembersBegin(); itx != group1->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer)
				{
					if( ar->HasFreeSlots(0) )
						ar->AddPlayer((*itx)->m_loggedInPlayer, 0);
				}
			}

			for(itx = group2->GetSubGroup(0)->GetGroupMembersBegin(); itx != group2->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer)
				{
					if( ar->HasFreeSlots(1) )
						ar->AddPlayer((*itx)->m_loggedInPlayer, 1);
				}
			}
		}
	}

	m_queueLock.Release();
	m_instanceLock.Release();
}
예제 #6
0
void CBattlegroundManager::HandleArenaJoin(WorldSession * m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match)
{
	uint32 pguid = m_session->GetPlayer()->GetLowGUID();
	uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
	if(as_group && m_session->GetPlayer()->GetGroup() == NULL)
		return;

	Group * pGroup = m_session->GetPlayer()->GetGroup();
	if(as_group)
	{
		if(pGroup->GetSubGroupCount() != 1)
		{
			m_session->SystemMessage("Sorry, raid groups joining battlegrounds are currently unsupported.");
			return;
		}
		if(pGroup->GetLeader() != m_session->GetPlayer()->m_playerInfo)
		{
			m_session->SystemMessage("You must be the party leader to add a group to an arena.");
			return;
		}

		GroupMembersSet::iterator itx;
		if(!rated_match)
		{
			/* add all players normally.. bleh ;P */
			pGroup->Lock();
			for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg)
					HandleArenaJoin((*itx)->m_loggedInPlayer->GetSession(), BattlegroundType, 0, 0);
			}
			pGroup->Unlock();
			return;
		}
		else
		{
			/* make sure all players are 70 */
			uint32 maxplayers;
			uint32 arenateamtype;
			switch(BattlegroundType)
			{
			case BATTLEGROUND_ARENA_2V2:
				arenateamtype=0;
				maxplayers=2;
				break;

			case BATTLEGROUND_ARENA_3V3:
				arenateamtype=1;
				maxplayers=3;
				break;

			case BATTLEGROUND_ARENA_5V5:
				arenateamtype=2;
				maxplayers=5;
				break;

			default:
				arenateamtype=0;
				maxplayers=2;
				break;
			}

			uint32 team_id = 0;

			pGroup->Lock();
			for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if( maxplayers == 0 )
				{
					m_session->SystemMessage("You have too many players in your party to join this type of arena.");
					pGroup->Unlock();
					return;
				}

				if((*itx)->lastLevel < 70)
				{
					m_session->SystemMessage("Sorry, some of your party members are not level 70.");
					pGroup->Unlock();
					return;
				}

				if((*itx)->m_loggedInPlayer)
				{
					ArenaTeam * t = (*itx)->m_loggedInPlayer->m_arenaTeams[arenateamtype];
					if( t != NULL )
					{
						if ( team_id == 0 )
							team_id = t->m_id;

						if ( team_id != t->m_id )
						{
							m_session->SystemMessage("Sorry, not all your party members are in same arena team.");
							pGroup->Unlock();
							return;
						}
					}
					else
					{
						m_session->SystemMessage("Sorry, not all your party members are in same arena team.");
						pGroup->Unlock();
						return;
					}

					if( (*itx)->m_loggedInPlayer->m_bgIsQueued )
						BattlegroundManager.RemovePlayerFromQueues((*itx)->m_loggedInPlayer);

					/*
					if((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued)
					{
						m_session->SystemMessage("One or more of your party members are already queued or inside a battleground.");
						pGroup->Unlock();
						return;
					}
					*/

					--maxplayers;
				}
			}
			if( maxplayers > 0 )
			{
				m_session->SystemMessage("Sorry, you have too few valid arena members in your group.");
				pGroup->Unlock();
				return;
			}

			WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
			data << uint32(6);		// all arenas

			for(itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
			{
				if((*itx)->m_loggedInPlayer)
				{
					SendBattlefieldStatus((*itx)->m_loggedInPlayer, 1, BattlegroundType, 0 , 0, 0,1);
					(*itx)->m_loggedInPlayer->m_bgIsQueued = true;
					(*itx)->m_loggedInPlayer->m_bgQueueInstanceId = 0;
					(*itx)->m_loggedInPlayer->m_bgQueueType = BattlegroundType;
					(*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data);
					(*itx)->m_loggedInPlayer->m_bgEntryPointX=(*itx)->m_loggedInPlayer->GetPositionX();
					(*itx)->m_loggedInPlayer->m_bgEntryPointY=(*itx)->m_loggedInPlayer->GetPositionY();
					(*itx)->m_loggedInPlayer->m_bgEntryPointZ=(*itx)->m_loggedInPlayer->GetPositionZ();
					(*itx)->m_loggedInPlayer->m_bgEntryPointMap=(*itx)->m_loggedInPlayer->GetMapId();
				}
			}

			pGroup->Unlock();

			m_queueLock.Acquire();
			m_queuedGroups[BattlegroundType].push_back(pGroup->GetID());
			m_queueLock.Release();
			Log.Success("BattlegroundMgr", "Group %u is now in battleground queue for arena type %u", pGroup->GetID(), BattlegroundType);

			/* send the battleground status packet */

			return;
		}
	}
	

	/* Queue him! */
	m_queueLock.Acquire();
	m_queuedPlayers[BattlegroundType][lgroup].push_back(pguid);
	Log.Success("BattlegroundMgr", "Player %u is now in battleground queue for {Arena %u}", m_session->GetPlayer()->GetLowGUID(), BattlegroundType );

	/* send the battleground status packet */
	SendBattlefieldStatus(m_session->GetPlayer(), 1, BattlegroundType, 0 , 0, 0,0);
	m_session->GetPlayer()->m_bgIsQueued = true;
	m_session->GetPlayer()->m_bgQueueInstanceId = 0;
	m_session->GetPlayer()->m_bgQueueType = BattlegroundType;

	/* Set battleground entry point */
	m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
	m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
	m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
	m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
	m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID();

	m_queueLock.Release();
}
예제 #7
0
void CBattlegroundManager::EventQueueUpdate()
{
	deque<Player*> tempPlayerVec[2];
	uint32 i,j,k;
	Player * plr;
	CBattleground * bg;
	list<uint32>::iterator it3, it4;
	//vector<Player*>::iterator it6;
	map<uint32, CBattleground*>::iterator iitr;
	Arena * arena;
	int32 team;
	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();

			for(it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
			{
				it4 = it3++;
                plr = objmgr.GetPlayer(*it4);
				
				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
						plr->GetSession()->SystemMessage("Your queue on battleground instance id %u is no longer valid. Reason: Instance Deleted.", plr->m_bgQueueInstanceId);
						plr->m_bgIsQueued = false;
						plr->m_bgQueueType = 0;
						plr->m_bgQueueInstanceId = 0;
						m_queuedPlayers[i][j].erase(it4);
					}

					// can we join?
					bg = iitr->second;
					if(bg->CanPlayerJoin(plr))
					{
						bg->AddPlayer(plr, plr->GetTeam());
						m_queuedPlayers[i][j].erase(it4);
					}
				}
				else
				{
					if(IS_ARENA(i))
						tempPlayerVec[0].push_back(plr);
					else
						tempPlayerVec[plr->GetTeam()].push_back(plr);
				}
			}

			// try to join existing instances
			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 = ((Arena*)iitr->second);
					if(arena->Rated())
						continue;

					team = arena->GetFreeTeam();
					while(team >= 0 && tempPlayerVec[0].size())
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();
						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						team = arena->GetFreeTeam();
					}
				}
				else
				{
					bg = iitr->second;
					for(k = 0; k < 2; ++k)
					{
						while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
						{
							plr = *tempPlayerVec[k].begin();
							tempPlayerVec[k].pop_front();
							bg->AddPlayer(plr, plr->GetTeam());
							ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
						}
					}
				}
			}

			if(IS_ARENA(i))
			{
				// enough players to start a round?
				if(tempPlayerVec[0].size() < BGMinimumPlayers[i])
					continue;

				if(CanCreateInstance(i,j))
				{
					arena = ((Arena*)CreateInstance(i, j));
					team = arena->GetFreeTeam();
					while(!arena->IsFull() && tempPlayerVec[0].size() && team >= 0)
					{
						plr = *tempPlayerVec[0].begin();
						tempPlayerVec[0].pop_front();

						plr->m_bgTeam=team;
						arena->AddPlayer(plr, team);
						team = arena->GetFreeTeam();

						// remove from the main queue (painful!)
						ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
					}
				}
			}
			else
			{
#ifdef ONLY_ONE_PERSON_REQUIRED_TO_JOIN_DEBUG
				if(tempPlayerVec[0].size() >= 1 ||
					tempPlayerVec[1].size() >= 1)
#else
				if(tempPlayerVec[0].size() >= BGMinimumPlayers[i] &&
					tempPlayerVec[1].size() >= BGMinimumPlayers[i])
#endif
				{
					if(CanCreateInstance(i,j))
					{
						bg = CreateInstance(i,j);
						if( bg == NULL )
						{
							// creation failed
							for(k = 0; k < 2; ++k)
							{
								while(tempPlayerVec[k].size())
								{
									plr = *tempPlayerVec[k].begin();
									tempPlayerVec[k].pop_front();
									ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
								}
							}
						}
						else
						{						
							// push as many as possible in
							for(k = 0; k < 2; ++k)
							{
								while(tempPlayerVec[k].size() && bg->HasFreeSlots(k))
								{
									plr = *tempPlayerVec[k].begin();
									tempPlayerVec[k].pop_front();
									plr->m_bgTeam=k;
									bg->AddPlayer(plr, k);
									ErasePlayerFromList(plr->GetLowGUID(), &m_queuedPlayers[i][j]);
								}
							}
						}
					}
				}
			}
		}
	}

	/* Handle paired arena team joining */
	list<uint32>::iterator itz;
	list<uint32>::iterator itp;
	for(i = BATTLEGROUND_ARENA_2V2; i < BATTLEGROUND_ARENA_5V5+1; ++i)
	{
		// We need at least this many :(
		if(m_queuedGroups[i].size() < 2)
			continue;

		list<uint32> removegroups;
		for(itz = m_queuedGroups[i].begin(); itz != m_queuedGroups[i].end(); itz++)
		{
			Group * pGroup = objmgr.GetGroupById(*itz);
			if(!pGroup || !pGroup->m_isqueued || !pGroup->GetLeader() || pGroup->GetLeader()->arenaTeam[i - 4] == NULL) continue;

			uint32 maxRange = pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange;
			pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange += 100;

			vector<uint32> inRangeGroups;

			uint32 rating = pGroup->GetLeader()->arenaTeam[i - 4]->m_stat_rating;
			for(itp = m_queuedGroups[i].begin(); itp != m_queuedGroups[i].end();)
			{
				Group * tGrp = objmgr.GetGroupById(*itp);
				if(!tGrp || !tGrp->m_isqueued || !tGrp->GetLeader() || tGrp->GetLeader()->arenaTeam[i - 4] == NULL)
				{
					itp = m_queuedGroups[i].erase(itp);
					continue;
				}

				++itp;

				if( pGroup == tGrp )
					continue;

				uint32 tRating = tGrp->GetLeader()->arenaTeam[i - 4]->m_stat_rating;

				int32 diff = (int32)tRating - (int32)rating;
				if(diff < 0)
					diff = -diff;

				if(diff > (int32)maxRange)
					continue;

				//Log.Notice("Debug", "EventQueueUpdate added 1 in range arena");

				inRangeGroups.push_back(tGrp->GetID());
			}

			// K, we have a giant list of groups that we could group with, hopefully!
			// or not, we can't go on :(
			if(!inRangeGroups.size())
				continue;

			// But if we're here, we can :D
			uint32 r = 0;
			if( inRangeGroups.size() > 1 )
				r = RandomUInt((uint32)inRangeGroups.size() - 1);

			Group * pairGroup = objmgr.GetGroupById(inRangeGroups[r]);
			if(!pairGroup) continue;

			// Now, let's create this rated Arena Match :)

			//Log.Notice("Debug", "EventQueueUpdate creating arena");
			Arena * arena = (Arena*)CreateInstance(i, LEVEL_GROUP_70);
			ArenaTeam *pTeamPair[2];

			if(arena)
			{
				//Log.Notice("Debug", "EventQueueUpdate arena created");
				removegroups.push_back(pGroup->GetID());
				removegroups.push_back(pairGroup->GetID());
				pGroup->m_isqueued = false;
				pairGroup->m_isqueued = false;
				arena->rated_match = true;
				if( pGroup->GetLeader()->arenaTeam[i - 4] != NULL )
				{
					arena->m_ratedTeams[0] = pGroup->GetLeader()->arenaTeam[i - 4]->m_id;
					pTeamPair[0] = pGroup->GetLeader()->arenaTeam[i - 4];
				}
				else
					pTeamPair[0] = NULL;
				
				if( pairGroup->GetLeader()->arenaTeam[i - 4] != NULL )
				{
					arena->m_ratedTeams[1] = pairGroup->GetLeader()->arenaTeam[i - 4]->m_id;
					pTeamPair[1] = pairGroup->GetLeader()->arenaTeam[i - 4];
				}
				else
					pTeamPair[1] = NULL;

				pGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100;
				pairGroup->GetLeader()->arenaTeam[i - 4]->m_queueSearchRange = 100;
				GroupMembersSet::iterator gitr;
				pGroup->Lock();
				for(gitr = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++)
				{
					PlayerInfo * pi = (*gitr);
					if(!pi->m_loggedInPlayer)
						continue;

					//Log.Notice("Debug", "EventQueueUpdate player lewp");
					pi->m_loggedInPlayer->m_bgTeam = 0;
					if(arena->HasFreeSlots(0))
					{
						arena->AddPlayer(pi->m_loggedInPlayer, 0);
						arena->m_RatedPlayers[0].insert(pi);
						if( pTeamPair[0] != NULL )
						{
							ArenaTeamMember * atm = pTeamPair[0]->GetMember(pi);
							if(atm)
							{
								atm->Played_ThisSeason++;
								atm->Played_ThisWeek++;
							}
							//Log.Notice("Debug", "EventQueueUpdate added player %s", pi->m_loggedInPlayer->GetName());
						}
					}
				}
				pGroup->Unlock();
				pairGroup->Lock();
				for(gitr = pairGroup->GetSubGroup(0)->GetGroupMembersBegin(); gitr != pairGroup->GetSubGroup(0)->GetGroupMembersEnd(); gitr++)
				{
					PlayerInfo * pi = (*gitr);
					if(!pi->m_loggedInPlayer || pi->arenaTeam[i-4] == NULL)
						continue;

					pi->m_loggedInPlayer->m_bgTeam = 1;
					if(arena->HasFreeSlots(1))
					{
						arena->AddPlayer(pi->m_loggedInPlayer, 1);
						arena->m_RatedPlayers[1].insert(pi);
						if( pTeamPair[1] != NULL )
						{
							ArenaTeamMember * atm = pTeamPair[1]->GetMember(pi);
							if(atm)
							{
								atm->Played_ThisSeason++;
								atm->Played_ThisWeek++;
							}
						}
					}
				}
				pairGroup->Unlock();
			}
		}


		for(itz = removegroups.begin(); itz != removegroups.end(); itz++)
		{
			m_queuedGroups[i].remove(*itz);
		}
	}

	m_queueLock.Release();
	m_instanceLock.Release();
}
예제 #8
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();
}
예제 #9
0
void CBattlegroundManager::HandleGetBattlegroundQueueCommand(WorldSession* m_session)
{
    std::stringstream ss;

    uint32 i, j;
    Player* plr;
    list<uint32>::iterator it3, it4;

    m_queueLock.Acquire();

    bool foundSomething = false;

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

            foundSomething = true;

            ss << m_session->LocalizedWorldSrv(GetBattlegroundCaption((BattleGroundTypes)i));

            switch (j)
            {
                case 0:
                    ss << " (<10)";
                    break;
                case 1:
                    ss << " (<20)";
                    break;
                case 2:
                    ss << " (<30)";
                    break;
                case 3:
                    ss << " (<40)";
                    break;
                case 4:
                    ss << " (<50)";
                    break;
                case 5:
                    ss << " (<60)";
                    break;
                case 6:
                    ss << " (<70)";
                    break;
                case 7:
                    ss << " (<80)";
                    break;
            }

            ss << ": ";

            ss << (uint32)m_queuedPlayers[i][j].size() << " players queued";

            if (!IS_ARENA(i))
            {
                int ally = 0, horde = 0;

                for (it3 = m_queuedPlayers[i][j].begin(); it3 != m_queuedPlayers[i][j].end();)
                {
                    it4 = it3++;
                    plr = objmgr.GetPlayer(*it4);

                    if (!plr || GetLevelGrouping(plr->getLevel()) != j)
                    {
                        continue;
                    }

                    if (plr->IsTeamAlliance())
                        ally++;
                    else
                        horde++;
                }

                ss << " (Alliance: " << ally << " Horde: " << horde;
                if ((int)m_queuedPlayers[i][j].size() > (ally + horde))
                    ss << " Unknown: " << ((int)m_queuedPlayers[i][j].size() - ally - horde);
                ss << ")";
            }

            m_session->SystemMessage(ss.str().c_str());
            ss.rdbuf()->str("");
        }

        if (IS_ARENA(i))
        {
            if (m_queuedGroups[i].size())
            {
                foundSomething = true;

                ss << m_session->LocalizedWorldSrv(GetBattlegroundCaption((BattleGroundTypes)i)) << " (rated): ";
                ss << (uint32)m_queuedGroups[i].size() << " groups queued";

                m_session->SystemMessage(ss.str().c_str());
                ss.rdbuf()->str("");
            }
        }
    }

    m_queueLock.Release();

    if (!foundSomething)
        m_session->SystemMessage("There's nobody queued.");
}
예제 #10
0
void CBattlegroundManager::HandleBattlegroundJoin(WorldSession* m_session, WorldPacket& pck)
{

    uint64 guid;
    uint32 pguid = m_session->GetPlayer()->GetLowGUID();
    uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
    uint32 bgtype;
    uint32 instance;

    pck >> guid >> bgtype >> instance;

    // Random battlegrounds aren't yet implemented
    if (bgtype == BATTLEGROUND_RANDOM)
        return;

    if ((bgtype >= BATTLEGROUND_NUM_TYPES) || (bgtype == 0) ||
        ((bgMaps.find(bgtype) == bgMaps.end()) && bgtype != BATTLEGROUND_RANDOM))
    {
        sCheatLog.writefromsession(m_session, "tried to crash the server by joining battleground that does not exist (0)");
        m_session->Disconnect();
        return;      // cheater!
    }

    /* Check the instance id */
    if (instance)
    {
        /* We haven't picked the first instance. This means we've specified an instance to join. */
        m_instanceLock.Acquire();
        map<uint32, CBattleground*>::iterator itr = m_instances[bgtype].find(instance);

        if (itr == m_instances[bgtype].end())
        {
            sChatHandler.SystemMessage(m_session, m_session->LocalizedWorldSrv(51));
            m_instanceLock.Release();
            return;
        }

        m_instanceLock.Release();
    }

    /* Queue him! */
    m_queueLock.Acquire();
    m_queuedPlayers[bgtype][lgroup].push_back(pguid);
    Log.Notice("BattlegroundManager", "Player %u is now in battleground queue for instance %u", m_session->GetPlayer()->GetLowGUID(), (instance + 1));

    /* send the battleground status packet */
    SendBattlefieldStatus(m_session->GetPlayer(), BGSTATUS_INQUEUE, bgtype, instance, 0, bgMaps[bgtype], 0);
    m_session->GetPlayer()->m_bgIsQueued = true;
    m_session->GetPlayer()->m_bgQueueInstanceId = instance;
    m_session->GetPlayer()->m_bgQueueType = bgtype;

    /* Set battleground entry point */
    m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
    m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
    m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
    m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
    m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID();

    m_queueLock.Release();

    /* We will get updated next few seconds =) */
}
예제 #11
0
void CBattlegroundManager::HandleArenaJoin(WorldSession* m_session, uint32 BattlegroundType, uint8 as_group, uint8 rated_match)
{
    uint32 pguid = m_session->GetPlayer()->GetLowGUID();
    uint32 lgroup = GetLevelGrouping(m_session->GetPlayer()->getLevel());
    if (as_group && m_session->GetPlayer()->GetGroup() == NULL)
        return;

    Group* pGroup = m_session->GetPlayer()->GetGroup();
    if (as_group)
    {
        if (pGroup->GetSubGroupCount() != 1)
        {
            m_session->SystemMessage(m_session->LocalizedWorldSrv(55));
            return;
        }
        if (pGroup->GetLeader() != m_session->GetPlayer()->getPlayerInfo())
        {
            m_session->SystemMessage(m_session->LocalizedWorldSrv(56));
            return;
        }

        GroupMembersSet::iterator itx;
        if (!rated_match)
        {
            /* add all players normally.. bleh ;P */
            pGroup->Lock();
            for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
            {
                if ((*itx)->m_loggedInPlayer && !(*itx)->m_loggedInPlayer->m_bgIsQueued && !(*itx)->m_loggedInPlayer->m_bg)
                    HandleArenaJoin((*itx)->m_loggedInPlayer->GetSession(), BattlegroundType, 0, 0);
            }
            pGroup->Unlock();
            return;
        }
        else
        {
            /* make sure all players are 70 */
            uint32 maxplayers;
            uint32 type = BattlegroundType - BATTLEGROUND_ARENA_2V2;
            switch (BattlegroundType)
            {
                case BATTLEGROUND_ARENA_3V3:
                    maxplayers = 3;
                    break;

                case BATTLEGROUND_ARENA_5V5:
                    maxplayers = 5;
                    break;

                case BATTLEGROUND_ARENA_2V2:
                default:
                    maxplayers = 2;
                    break;
            }

            if (pGroup->GetLeader()->m_loggedInPlayer && pGroup->GetLeader()->m_loggedInPlayer->m_arenaTeams[type] == NULL)
            {
                m_session->SendNotInArenaTeamPacket(uint8(maxplayers));
                return;
            }

            pGroup->Lock();
            for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
            {
                if (maxplayers == 0)
                {
                    m_session->SystemMessage(m_session->LocalizedWorldSrv(58));
                    pGroup->Unlock();
                    return;
                }

                if ((*itx)->lastLevel < PLAYER_ARENA_MIN_LEVEL)
                {
                    m_session->SystemMessage(m_session->LocalizedWorldSrv(59));
                    pGroup->Unlock();
                    return;
                }

                if ((*itx)->m_loggedInPlayer)
                {
                    if ((*itx)->m_loggedInPlayer->m_bg || (*itx)->m_loggedInPlayer->m_bgIsQueued)
                    {
                        m_session->SystemMessage(m_session->LocalizedWorldSrv(60));
                        pGroup->Unlock();
                        return;
                    };
                    if ((*itx)->m_loggedInPlayer->m_arenaTeams[type] != pGroup->GetLeader()->m_loggedInPlayer->m_arenaTeams[type])
                    {
                        m_session->SystemMessage(m_session->LocalizedWorldSrv(61));
                        pGroup->Unlock();
                        return;
                    }

                    --maxplayers;
                }
            }
            WorldPacket data(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
            data << uint32(6);      // all arenas

            for (itx = pGroup->GetSubGroup(0)->GetGroupMembersBegin(); itx != pGroup->GetSubGroup(0)->GetGroupMembersEnd(); ++itx)
            {
                if ((*itx)->m_loggedInPlayer)
                {
                    SendBattlefieldStatus((*itx)->m_loggedInPlayer, BGSTATUS_INQUEUE, BattlegroundType, 0, 0, 0, 1);
                    (*itx)->m_loggedInPlayer->m_bgIsQueued = true;
                    (*itx)->m_loggedInPlayer->m_bgQueueInstanceId = 0;
                    (*itx)->m_loggedInPlayer->m_bgQueueType = BattlegroundType;
                    (*itx)->m_loggedInPlayer->GetSession()->SendPacket(&data);
                    (*itx)->m_loggedInPlayer->m_bgEntryPointX = (*itx)->m_loggedInPlayer->GetPositionX();
                    (*itx)->m_loggedInPlayer->m_bgEntryPointY = (*itx)->m_loggedInPlayer->GetPositionY();
                    (*itx)->m_loggedInPlayer->m_bgEntryPointZ = (*itx)->m_loggedInPlayer->GetPositionZ();
                    (*itx)->m_loggedInPlayer->m_bgEntryPointMap = (*itx)->m_loggedInPlayer->GetMapId();
                }
            }

            pGroup->Unlock();

            m_queueLock.Acquire();
            m_queuedGroups[BattlegroundType].push_back(pGroup->GetID());
            m_queueLock.Release();
            Log.Notice("BattlegroundMgr", "Group %u is now in battleground queue for arena type %u", pGroup->GetID(), BattlegroundType);

            /* send the battleground status packet */

            return;
        }
    }


    /* Queue him! */
    m_queueLock.Acquire();
    m_queuedPlayers[BattlegroundType][lgroup].push_back(pguid);
    Log.Notice("BattlegroundMgr", "Player %u is now in battleground queue for {Arena %u}", m_session->GetPlayer()->GetLowGUID(), BattlegroundType);

    /* send the battleground status packet */
    SendBattlefieldStatus(m_session->GetPlayer(), BGSTATUS_INQUEUE, BattlegroundType, 0, 0, 0, 0);
    m_session->GetPlayer()->m_bgIsQueued = true;
    m_session->GetPlayer()->m_bgQueueInstanceId = 0;
    m_session->GetPlayer()->m_bgQueueType = BattlegroundType;

    /* Set battleground entry point */
    m_session->GetPlayer()->m_bgEntryPointX = m_session->GetPlayer()->GetPositionX();
    m_session->GetPlayer()->m_bgEntryPointY = m_session->GetPlayer()->GetPositionY();
    m_session->GetPlayer()->m_bgEntryPointZ = m_session->GetPlayer()->GetPositionZ();
    m_session->GetPlayer()->m_bgEntryPointMap = m_session->GetPlayer()->GetMapId();
    m_session->GetPlayer()->m_bgEntryPointInstance = m_session->GetPlayer()->GetInstanceID();

    m_queueLock.Release();
}
예제 #12
0
bool CBattleground::CanPlayerJoin(Player* plr, uint32 type)
{
	return HasFreeSlots(plr->m_bgTeam, type) && (GetLevelGrouping(plr->getLevel()) == GetLevelGroup()) && (!plr->HasAura(BG_DESERTER));
}