//-----------------------------------------------------------------------------
// Purpose: sets the specified component bit # if it is not already.
//			If it does get set, evaluate if this satisfies an achievement
//-----------------------------------------------------------------------------
void CBaseAchievement::EnsureComponentBitSetAndEvaluate( int iBitNumber )
{
	Assert( iBitNumber < 64 );	// this is bit #, not a bit mask

	if ( IsAchieved() )
		return;

	// calculate which bit this component corresponds to
	uint64 iBitMask = ( (uint64) 1 ) << iBitNumber;

	// see if we already have gotten this component
	if ( 0 == ( iBitMask & m_iComponentBits ) )
	{				
		if ( !AlwaysEnabled() && !m_pAchievementMgr->CheckAchievementsEnabled() )
		{
			Msg( "Achievements disabled, ignoring achievement component for %s\n", GetName() );
			return;
		}

		// new component, set the bit and increment the count
		SetComponentBits( m_iComponentBits | iBitMask );
		if ( m_iCount != m_iGoal )
		{
			// save our state at the next good opportunity
			m_pAchievementMgr->SetDirty( true );		

			if ( cc_achievement_debug.GetInt() )
			{
				Msg( "Component %d for achievement %s found\n", iBitNumber, GetName() );
			}

			ShowProgressNotification();
		}				
	}
	else
	{
		if ( cc_achievement_debug.GetInt() )
		{
			Msg( "Component %d for achievement %s found, but already had that component\n", iBitNumber, GetName() );
		}
	}

	// Check to see if we've achieved our goal even if the bit is already set 
	// (this fixes some older achievements that are stuck in the 9/9 state and could never be evaluated)
	Assert( m_iCount <= m_iGoal );
	if ( m_iCount == m_iGoal )
	{
		// all components found, award the achievement (and save state)
		AwardAchievement();
	}
}
//-----------------------------------------------------------------------------
// Purpose: called when an event that counts toward an achievement occurs
//-----------------------------------------------------------------------------
void CBaseAchievement::IncrementCount( int iOptIncrement )
{
	if ( !IsAchieved() && LocalPlayerCanEarn() )
	{
		if ( !AlwaysEnabled() && !m_pAchievementMgr->CheckAchievementsEnabled() )
		{
			Msg( "Achievements disabled, ignoring achievement progress for %s\n", GetName() );
			return;
		}

		// on client, where the count is kept, increment count
		if ( iOptIncrement > 0 )
		{
			// user specified that we want to increase by more than one.
			m_iCount += iOptIncrement;
			if ( m_iCount > m_iGoal )
			{
				m_iCount = m_iGoal;
			}
		}
		else
		{
			m_iCount++;
		}

		// if this achievement gets saved w/global state, flag our global state as dirty
		if ( GetFlags() & ACH_SAVE_GLOBAL )
		{
			m_pAchievementMgr->SetDirty( true );
		}

		if ( cc_achievement_debug.GetInt() )
		{
			Msg( "Achievement count increased for %s: %d/%d\n", GetName(), m_iCount, m_iGoal );
		}

#ifndef NO_STEAM
		// if this achievement's progress should be stored in Steam, set the steam stat for it
		if ( StoreProgressInSteam() && steamapicontext->SteamUserStats() )
		{
			// Set the Steam stat with the same name as the achievement.  Only cached locally until we upload it.
			char pszProgressName[1024];
			Q_snprintf( pszProgressName, 1024, "%s_STAT", GetStat() );
			bool bRet = steamapicontext->SteamUserStats()->SetStat( pszProgressName, m_iCount );
			if ( !bRet )
			{
				DevMsg( "ISteamUserStats::GetStat failed to set progress value in Steam for achievement %s\n", pszProgressName );
			}

			m_pAchievementMgr->SetDirty( true );
		}
#endif
		// if we've hit goal, award the achievement
		if ( m_iGoal > 0 )
		{
			if ( m_iCount >= m_iGoal )
			{
				AwardAchievement();
			}
			else
			{	
				HandleProgressUpdate();
			}
		}

	}
}