コード例 #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);
	}
}
コード例 #2
0
ファイル: BattlegroundMgr.cpp プロジェクト: Chero/abcwow
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();
}
コード例 #3
0
ファイル: BattlegroundMgr.cpp プロジェクト: AwkwardDev/Summit
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();
}
コード例 #4
0
ファイル: BattlegroundMgr.cpp プロジェクト: Declipe/AscEmu
CBattleground* CBattlegroundManager::CreateInstance(uint32 Type, uint32 LevelGroup)
{
    if (bgMaps.find(Type) == bgMaps.end())
    {
        if (!IS_ARENA(Type))
        {
            LOG_ERROR("BattlegroundManager", "No map Id is registered for Battleground type %u", Type);
            return NULL;
        }
    }

    BattlegroundFactoryMethod cfunc = NULL;

    if (!IS_ARENA(Type))
        if (bgFactories.find(bgMaps[Type]) != bgFactories.end())
            cfunc = bgFactories[bgMaps[Type]];

    MapMgr* mgr = NULL;
    CBattleground* bg;
    bool isWeekend = false;
    struct tm tm;
    uint32 iid;
    time_t t;
    int n;

    if (IS_ARENA(Type))
    {
        /* arenas follow a different procedure. */
        uint32 arenaMapCount = arenaMaps.size();
        if (arenaMapCount == 0)
        {
            LOG_ERROR("BattlegroundManager", "There are no Arenas registered. Cannot create Arena.");
            return NULL;
        }

        uint32 index = RandomUInt(arenaMapCount - 1);
        uint32 mapid = arenaMaps[index];
        ArenaFactoryMethod arenaFactory = arenaFactories[index];
        uint32 players_per_side;

        mgr = sInstanceMgr.CreateBattlegroundInstance(mapid);
        if (mgr == NULL)
        {
            sLog.Error("BattlegroundManager", "Arena CreateInstance() call failed for map %u, type %u, level group %u", mapid, Type, LevelGroup);
            return NULL;      // Shouldn't happen
        }

        players_per_side = GetMaximumPlayers(Type);

        iid = ++m_maxBattlegroundId[Type];
        bg = arenaFactory(mgr, iid, LevelGroup, Type, players_per_side);
        mgr->m_battleground = bg;
        Log.Notice("BattlegroundManager", "Created arena battleground type %u for level group %u on map %u.", Type, LevelGroup, mapid);
        sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1, 0);
        m_instanceLock.Acquire();
        m_instances[Type].insert(make_pair(iid, bg));
        m_instanceLock.Release();
        return bg;
    }

    if (cfunc == NULL)
    {
        sLog.Error("BattlegroundManager", "Could not find CreateBattlegroundFunc pointer for type %u level group %u", Type, LevelGroup);
        return NULL;
    }

    t = time(NULL);
#ifdef WIN32
    //    localtime_s(&tm, &t);
    //zack : some luv for vs2k3 compiler
    tm = *localtime(&t);
#else
    localtime_r(&t, &tm);
#endif

    switch (Type)
    {
        case BATTLEGROUND_WARSONG_GULCH:
            n = 0;
            break;
        case BATTLEGROUND_ARATHI_BASIN:
            n = 1;
            break;
        case BATTLEGROUND_EYE_OF_THE_STORM:
            n = 2;
            break;
        case BATTLEGROUND_STRAND_OF_THE_ANCIENT:
            n = 3;
            break;
        default:
            n = 0;
            break;
    }
    if (((tm.tm_yday / 7) % 4) == n)
    {
        /* Set weekend from Thursday night at midnight until Tuesday morning */
        isWeekend = tm.tm_wday >= 5 || tm.tm_wday < 2;
    }

    /* Create Map Manager */
    mgr = sInstanceMgr.CreateBattlegroundInstance(bgMaps[Type]);
    if (mgr == NULL)
    {
        sLog.Error("BattlegroundManager", "CreateInstance() call failed for map %u, type %u, level group %u", bgMaps[Type], Type, LevelGroup);
        return NULL;      // Shouldn't happen
    }

    /* Call the create function */
    iid = ++m_maxBattlegroundId[Type];
    bg = cfunc(mgr, iid, LevelGroup, Type);
    bg->SetIsWeekend(isWeekend);
    mgr->m_battleground = bg;
    sEventMgr.AddEvent(bg, &CBattleground::EventCreate, EVENT_BATTLEGROUND_QUEUE_UPDATE, 1, 1, 0);
    Log.Notice("BattlegroundManager", "Created battleground type %u for level group %u.", Type, LevelGroup);

    m_instanceLock.Acquire();
    m_instances[Type].insert(make_pair(iid, bg));
    m_instanceLock.Release();

    return bg;
}
コード例 #5
0
ファイル: BattlegroundMgr.cpp プロジェクト: Declipe/AscEmu
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();
}