Esempio n. 1
0
//-----------------------------------------------------------------------------
// Purpose: Get the next player from the queue, and shuffle the rest up
//-----------------------------------------------------------------------------
CBasePlayer *CDiscArena::GetNextPlayer( void )
{
	if ( m_pPlayerQueue == NULL )
		return NULL;

	CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue;
	RemovePlayerFromQueue( (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue );

	return pCurr;
}
Esempio n. 2
0
void WorldSession::HandleMeetingStoneLeaveOpcode(WorldPacket & recv_data)
{
	DEBUG_LOG("WORLD: Recvd CMSG_MEETINGSTONE_LEAVE");

	if (Group *grp = _player->GetGroup()) {

	}
	else {
		RemovePlayerFromQueue(_player->GetGUIDLow());
	}

	SendMeetingstoneSetqueue(0, MEETINGSTONE_STATUS_NONE);
}
Esempio n. 3
0
//-----------------------------------------------------------------------------
// Purpose: Client was removed from the arena
//-----------------------------------------------------------------------------
void CDiscArena::RemoveClient( CBasePlayer *pPlayer )
{
	m_iPlayers--;

	pPlayer->pev->groupinfo = 0;
	pPlayer->m_pCurrentArena = NULL;

	// Is she in the current battle?
	if ( pPlayer->pev->playerclass != 0 )
	{
		// No, she's in the queue, so remove her.
		RemovePlayerFromQueue( pPlayer );
	}
	else if ( m_iArenaState != ARENA_WAITING_FOR_PLAYERS )
	{
		// This team loses
		m_iWinningTeam = (pPlayer->pev->team == 1) ? 2 : 1;
		if ( m_iWinningTeam == 1 )
			m_iTeamOneScore = m_iMaxRounds - 1;		// -1 because we'll get 1 point for winning this round in CheckOverThink
		else
			m_iTeamTwoScore = m_iMaxRounds - 1;		// -1 because we'll get 1 point for winning this round in CheckOverThink

		// Find the player in the combatant list
		for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
		{
			// Check to see if this slot's already full
			if ( m_hCombatants[ i ] == pPlayer )
			{
				m_hCombatants[i] = NULL;
				break;
			}
		}

		CheckOverThink();
	}
}
Esempio n. 4
0
bool LFGQueue::FindRoleToGroup(Player* plr, Group* grp, ClassRoles role)
{
    // Safe check
    if(!plr || !grp)
        return false;

    QueuedGroupsMap::iterator qGroup = m_QueuedGroups.find(grp->GetId());
    QueuedPlayersMap::iterator qPlayer = m_QueuedPlayers.find(plr->GetObjectGuid());

    if(qGroup != m_QueuedGroups.end() && qPlayer != m_QueuedPlayers.end())
    {
        if (getPriority((Classes)plr->getClass(), role) >= LFG_PRIORITY_HIGH || qPlayer->second.hasQueuePriority)
        {
            bool hasBeenLongerInQueue = false;

            // Iterate over QueuedPlayersMap to find if players have been longer in Queue.
            for (QueuedPlayersMap::iterator qPlayer_loop = m_QueuedPlayers.begin(); qPlayer_loop != m_QueuedPlayers.end(); ++qPlayer_loop)
            {
                if (qPlayer->first == qPlayer_loop->first)
                    continue;

                if(qPlayer->second.timeInLFG > qPlayer_loop->second.timeInLFG)
                    hasBeenLongerInQueue = true;
            }

            if(hasBeenLongerInQueue)
            {
                switch(role)
                {
                    case LFG_ROLE_TANK:
                    {
                        // Remove tank flag if player can perform tank role.
                        qGroup->second.availableRoles &= ~LFG_ROLE_TANK;
                        break;
                    }

                    case LFG_ROLE_HEALER:
                    {
                        // Remove healer flag if player can perform healer role.
                        qGroup->second.availableRoles &= ~LFG_ROLE_HEALER;
                        break;
                    }

                    case LFG_ROLE_DPS:
                    {
                        if(qGroup->second.dpsCount < 3)
                        {
                            // Update dps count first.
                            ++qGroup->second.dpsCount;

                            // Remove dps flag if there is enough dps in group.
                            if(qGroup->second.dpsCount >= 3)
                                qGroup->second.availableRoles &= ~LFG_ROLE_DPS;
                        }
                        break;
                    }

                    default:
                    {
                        return false;
                    }
                }
            }

            WorldPacket data;
            BuildMemberAddedPacket(data, plr->GetGUID());
            grp->BroadcastPacket(&data, true);

            // Add member to the group.
            grp->AddMember(plr->GetObjectGuid(), plr->GetName(), GROUP_LFG);

            // Remove player from queue.
            RemovePlayerFromQueue(qPlayer->first, PLAYER_SYSTEM_LEAVE);

            // Found player return true.
            return true;
        }
        else if (getPriority((Classes)plr->getClass(), role) < LFG_PRIORITY_HIGH)
        {
            bool hasFoundPriority = false;
            bool hasBeenLongerInQueue = false;

            // Iterate over QueuedPlayersMap to find if players in queue have higher priority or they have been longer in Queue.
            for (QueuedPlayersMap::iterator qPlayer_loop = m_QueuedPlayers.begin(); qPlayer_loop != m_QueuedPlayers.end(); ++qPlayer_loop)
            {
                if (qPlayer->first == qPlayer_loop->first)
                    continue;

                Player* m_loopMember = sObjectMgr.GetPlayer(qPlayer_loop->first);

                // If there is anyone in group for class with higher priority then ignore current member.
                if (getPriority((Classes)plr->getClass(), role) < getPriority((Classes)m_loopMember->getClass(), role))
                    hasFoundPriority = true;

                if(qPlayer->second.timeInLFG > qPlayer_loop->second.timeInLFG)
                    hasBeenLongerInQueue = true;
            }

            // If there were no one in group for role with higher priority add this member to group
            if(!hasFoundPriority && hasBeenLongerInQueue)
            {
                switch(role)
                {
                    case LFG_ROLE_TANK:
                    {
                        // Remove tank flag if player can perform tank role.
                        qGroup->second.availableRoles &= ~LFG_ROLE_TANK;
                        break;
                    }

                    case LFG_ROLE_HEALER:
                    {
                        // Remove healer flag if player can perform healer role.
                        qGroup->second.availableRoles &= ~LFG_ROLE_HEALER;
                        break;
                    }

                    case LFG_ROLE_DPS:
                    {
                        if(qGroup->second.dpsCount < 3)
                        {
                            // Update dps count first.
                            ++qGroup->second.dpsCount;

                            // Remove dps flag if there is enough dps in group.
                            if(qGroup->second.dpsCount >= 3)
                                qGroup->second.availableRoles &= ~LFG_ROLE_DPS;
                        }
                        break;
                    }

                    // This is impossible...
                    default:
                    {
                        return false;
                    }
                }

                WorldPacket data;
                BuildMemberAddedPacket(data, plr->GetGUID());
                grp->BroadcastPacket(&data, true);

                // Add member to the group.
                grp->AddMember(plr->GetObjectGuid(), plr->GetName(), GROUP_LFG);

                // Now remove player from queue
                RemovePlayerFromQueue(qPlayer->first, PLAYER_SYSTEM_LEAVE);

                // found player return true
                return true;
            }
        }
    }

    return false;
}
Esempio n. 5
0
void LFGQueue::Update(uint32 diff)
{
    if(m_QueuedGroups.empty() && m_QueuedPlayers.empty())
        return;

    // Iterate over QueuedPlayersMap to update players timers and remove offline/disconnected players.
    for(QueuedPlayersMap::iterator qPlayer = m_QueuedPlayers.begin(); qPlayer != m_QueuedPlayers.end(); ++qPlayer)
    {
        Player* plr = sObjectMgr.GetPlayer(qPlayer->first);

        // Player could have been disconnected
        if(!plr ||!plr->IsInWorld())
        {
            m_OfflinePlayers[qPlayer->first] = qPlayer->second;
            m_QueuedPlayers.erase(qPlayer);
            break;
        }

        qPlayer->second.timeInLFG += diff;

        // Update player timer and give him queue priority.
        if(qPlayer->second.timeInLFG >= (30 * MINUTE * IN_MILLISECONDS))
        {
            qPlayer->second.hasQueuePriority = true;
        }
    }

    if(!m_QueuedGroups.empty())
    {
        // Iterate over QueuedGroupsMap to fill groups with roles they're missing.
        for(QueuedGroupsMap::iterator qGroup = m_QueuedGroups.begin(); qGroup != m_QueuedGroups.end(); ++qGroup)
        {
            Group* grp = sObjectMgr.GetGroupById(qGroup->first);

            // Safe check
            if(!grp)
                return;

            // Remove group from Queue if it's full
            if(grp->IsFull())
            {
                RemoveGroupFromQueue(qGroup->first, GROUP_SYSTEM_LEAVE);
                break;
            }

            // Iterate over QueuedPlayersMap to find suitable player to join group
            for(QueuedPlayersMap::iterator qPlayer = m_QueuedPlayers.begin(); qPlayer != m_QueuedPlayers.end(); ++qPlayer)
            {
                Player* plr = sObjectMgr.GetPlayer(qPlayer->first);

                // Check here that players team and areaId they're in queue are same
                if(qPlayer->second.team == qGroup->second.team &&
                   qPlayer->second.areaId == qGroup->second.areaId)
                {
                    // Check if player can perform tank role
                    if((canPerformRole(qPlayer->second.roleMask, LFG_ROLE_TANK) & qGroup->second.availableRoles) == LFG_ROLE_TANK)
                    {
                        if(FindRoleToGroup(plr, grp, LFG_ROLE_TANK))
                        {
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    // Check if player can perform healer role
                    if((canPerformRole(qPlayer->second.roleMask, LFG_ROLE_HEALER) & qGroup->second.availableRoles) == LFG_ROLE_HEALER)
                    {
                        if(FindRoleToGroup(plr, grp, LFG_ROLE_HEALER))
                        {
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    // Check if player can perform dps role
                    if((canPerformRole(qPlayer->second.roleMask, LFG_ROLE_DPS) & qGroup->second.availableRoles) == LFG_ROLE_DPS)
                    {
                        if(FindRoleToGroup(plr, grp, LFG_ROLE_DPS))
                        {
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    // Check if group is full, no need to try to iterate same group if it's already full.
                    if(grp->IsFull())
                    {
                        RemoveGroupFromQueue(qGroup->first, GROUP_SYSTEM_LEAVE);
                        break;
                    }
                }
            }

            // Update group timer. After each 5 minutes group will be broadcasted they're still waiting more members.
            if (qGroup->second.groupTimer <= diff)
            {
                WorldPacket data;
                BuildInProgressPacket(data);

                grp->BroadcastPacket(&data, true);

                qGroup->second.groupTimer = 5 * MINUTE * IN_MILLISECONDS;
            }
            else
            {
                qGroup->second.groupTimer -= diff;
            }
        }
    }

    // Pick first 2 players and form group out of them also inserting them into queue as group.
    if(m_QueuedPlayers.size() > 5)
    {
        // Pick Leader as first target.
        QueuedPlayersMap::iterator nPlayer1 = m_QueuedPlayers.begin();

        if(findInArea(nPlayer1->second.areaId) > 5)
        {
            Group* newQueueGroup = new Group;

            // Iterate of QueuedPlayersMap and pick first member to accompany leader.
            for(QueuedPlayersMap::iterator nPlayer2 = m_QueuedPlayers.begin(); nPlayer2 != m_QueuedPlayers.end(); ++nPlayer2)
            {
                if(nPlayer1->first == nPlayer2->first)
                    continue;

                if(nPlayer1->second.team == nPlayer2->second.team &&
                    nPlayer1->second.areaId == nPlayer2->second.areaId)
                {
                    Player* leader = sObjectMgr.GetPlayer(nPlayer1->first);
                    Player* member = sObjectMgr.GetPlayer(nPlayer2->first);
                    uint32 areaId = nPlayer1->second.areaId;

                    if(!newQueueGroup->IsCreated())
                    {
                        if(newQueueGroup->Create(leader->GetObjectGuid(), leader->GetName()))
                            sObjectMgr.AddGroup(newQueueGroup);
                        else
                            return;
                    }

                    WorldPacket data;
                    BuildMemberAddedPacket(data, member->GetGUID());

                    leader->GetSession()->SendPacket(&data);

                    // Add member to the group. Leader is already added upon creation of group.
                    newQueueGroup->AddMember(member->GetObjectGuid(), member->GetName(), GROUP_LFG);

                    // Add this new group to GroupQueue now and remove players from PlayerQueue
                    RemovePlayerFromQueue(nPlayer1->first, PLAYER_SYSTEM_LEAVE);
                    RemovePlayerFromQueue(nPlayer2->first, PLAYER_SYSTEM_LEAVE);
                    AddToQueue(leader, areaId);

                    break;
                }
            }
        }
    }
}
Esempio n. 6
0
void WorldSession::LFGLoop() {

	QueryResult *result = WorldDatabase.Query("SELECT guid,zoneid,is_group FROM lfg_queue");
	if (result)
	{

		do
		{
			Field* fields = result->Fetch();

			//is this entry a group?
			if(fields[2].GetUInt32() == 1) {
				//is there anyone in the queue looking for a group for this groups instance?
				QueryResult *resultLFG = WorldDatabase.PQuery("SELECT guid,zoneid,is_group,player_name FROM lfg_queue WHERE zoneid = '%u' AND is_group = 0", fields[1].GetUInt32());
				if (resultLFG) {
					do
					{
						Field* fieldsLFG = resultLFG->Fetch();
						Player *plr = sObjectAccessor.FindPlayerByName(fieldsLFG[3].GetString());
						Group *grp = sObjectMgr.GetGroupById(fields[0].GetUInt32());

						if(!grp->IsFull()) {
							//check for roles
							if(GroupHasRole(ROLE_TANK, grp) && GroupHasRole(ROLE_HEALER, grp)) {
								//group has both dps & tank, add anyone.
								grp->AddMember(plr->GetGUID(), plr->GetName());
								RemovePlayerFromQueue(plr->GetGUIDLow());

								if(grp->IsFull()) {
									SendMeetingStoneCompleteToParty(grp);
								}
							}
							else if(GroupHasRole(ROLE_TANK, grp) && !GroupHasRole(ROLE_HEALER, grp)) {
								//tank but healers missing
								//is player healer?
								if(isPlayerHealer(plr)) {

									grp->AddMember(plr->GetGUID(), plr->GetName());
									RemovePlayerFromQueue(plr->GetGUIDLow());
									if(grp->IsFull()) {
										SendMeetingStoneCompleteToParty(grp);
									}

								}
								//player is not healer but group can take one more random..
								else if(!isPlayerHealer(plr) && grp->GetMembersCount() < 4) {
									grp->AddMember(plr->GetGUID(), plr->GetName());
									RemovePlayerFromQueue(plr->GetGUIDLow());
									if(grp->IsFull()) {
										SendMeetingStoneCompleteToParty(grp);
									}
								}
							}
							else if(!GroupHasRole(ROLE_TANK, grp) && !GroupHasRole(ROLE_HEALER, grp)) {
								//group has neither tank or healer
								if(isPlayerHealer(plr) || isPlayerTank(plr)) {
									grp->AddMember(plr->GetGUID(), plr->GetName());
									RemovePlayerFromQueue(plr->GetGUIDLow());
									if(grp->IsFull()) {
										SendMeetingStoneCompleteToParty(grp);
									}
								}
								else {
									if(grp->GetMembersCount() < 3) {
										//theres room for 1 more random, let the player join.
										grp->AddMember(plr->GetGUID(), plr->GetName());
										RemovePlayerFromQueue(plr->GetGUIDLow());
										if(grp->IsFull()) {
											SendMeetingStoneCompleteToParty(grp);
										}
									}
								}

							}
						}
					}
					while (resultLFG->NextRow());
				}

			}
			else {
				//its a player, is there any other non-grouped players thats looking for the same instance?

				QueryResult *result_mp = WorldDatabase.PQuery("SELECT guid,zoneid,is_group,player_name FROM lfg_queue WHERE zoneid = '%u' AND is_group = 0", fields[1].GetUInt32());
				if(result_mp->GetRowCount() > 1) {
					int i = 1;
					Group* grp;
					grp = new Group;
					do {
						
						Field* fields_mp = result_mp->Fetch();
						Player *plr = sObjectAccessor.FindPlayerByName(fields_mp[3].GetString());

						if(!grp->IsCreated()) {
							if (grp->Create(plr->GetGUID(), plr->GetName())) {
								sObjectMgr.AddGroup(grp);
								RemovePlayerFromQueue(plr->GetGUIDLow());
							}
						}
						else {
							grp->AddMember(plr->GetGUID(), plr->GetName());
							RemovePlayerFromQueue(plr->GetGUIDLow());
						}


						plr = NULL;

					}
					while (result_mp->NextRow());

					//if this group did not fill up, add it into LFM queue

					if(!grp->IsFull()) {

						AddGroupToQueue(grp->GetId(), fields[1].GetUInt32());
					}
				}



			}
		}
		while (result->NextRow());

	}

}