void CGEStats::SetAwardsInEvent( IGameEvent *pEvent )
{   
	// Ignore awards when only 1 person is playing
	if ( GEMPRules()->GetNumActivePlayers() < 2 )
		return;

	CUtlVector<GEStatSort*> vAwards;
	GEStatSort *award;
	int i;

	// Prevent divide by zero
	if ( m_iRoundCount == 0 )
		m_iRoundCount = 1;

	for ( i=0; i < GE_AWARD_GIVEMAX; i++ )
	{
		// Check for valid award
		if ( AwardIDToIdent(i) )
		{
			award = new GEStatSort;
			// See if we are going to give this one out, if so store it, if not erase the dummy var
			if ( GetAwardWinner(i, *award) )
				vAwards.AddToTail( award );
			else
				delete award;
		}
	}

	// Sort our ratios from High to Low
	vAwards.Sort( &CGEStats::StatSortHigh );

	char eventid[16], eventwinner[16];
	CBaseEntity *pPlayer;
	for ( i=0; i < vAwards.Count(); i++ )
	{
		// Never give out more than 6 awards
		if ( i == 6 )
			break;

		pPlayer = m_pPlayerStats[ vAwards[i]->idx ]->GetPlayer();
		if ( !pPlayer )
			continue;

		Q_snprintf( eventid, 16, "award%i_id", i+1 );
		Q_snprintf( eventwinner, 16, "award%i_winner", i+1 );

		pEvent->SetInt( eventid, vAwards[i]->m_iAward );
		pEvent->SetInt( eventwinner, pPlayer->entindex() );
	}

	vAwards.PurgeAndDeleteElements();
}
예제 #2
0
void CLightingEditor::RenderSprites()
{
	CMatRenderContextPtr pRenderContext( materials );
	pRenderContext->Bind( m_matSprite_Light );

	CUtlVector< def_light_t* > hSortedLights;
	hSortedLights.AddVectorToTail( m_hEditorLights );
	hSortedLights.Sort( DefLightSort );

	FOR_EACH_VEC( hSortedLights, i )
	{
		def_light_t *pLight = hSortedLights[ i ];

		Vector origin = pLight->pos;

		float flC3[3] = { 0 };
		float flMax = MAX( 1, MAX( pLight->col_diffuse[0],
			MAX( pLight->col_diffuse[1], pLight->col_diffuse[2] ) ) );

		for ( int i = 0; i < 3; i++ )
			flC3[i] = clamp( pLight->col_diffuse[i] / flMax, 0, 1 );

		DrawHalo( m_matSprite_Light, origin, LIGHT_BOX_SIZE, flC3 );
	}
bool CGEStats::GetFavoriteWeapon( int iPlayer, GEWeaponSort &fav )
{
	if ( iPlayer < 0 || iPlayer >= m_pPlayerStats.Count() )
		return false;

	GEPlayerStats *stats = m_pPlayerStats[iPlayer];
	CBasePlayer *pPlayer = ToBasePlayer( m_pPlayerStats[iPlayer]->GetPlayer() );

	if ( !pPlayer || !stats )
		return false;

	// We want raw kills, NOT score
	int playerFrags = pPlayer->FragCount();
	float roundtime = gpGlobals->curtime - m_flRoundStartTime;
	// Avoid divide by zero!
	if ( roundtime == 0.0f )
		roundtime = 0.5f;

	CUtlVector<GEWeaponSort*> weapons;
	float killPercent;

	for ( int i=WEAPON_NONE+1; i < WEAPON_RANDOM; i++ ) // Go up to WEAPON_RANDOM to exclude tokens.
	{
		GEWeaponSort *entry = new GEWeaponSort;
		if ( GEGameplay()->IsInFinalIntermission() )
		{
			entry->m_iPercentage = stats->m_iMatchWeapons[i];
		}
		else
		{
			// Avoid divide by zero!
			if ( playerFrags == 0 )
				killPercent = 0.0f;
			else
				killPercent = (float)stats->m_iWeaponsKills[i] / (float)playerFrags;

			if ( roundtime < 1.0f )
				entry->m_iPercentage = 0;
			else
				entry->m_iPercentage = 100 * ( ((float)stats->m_iWeaponsHeldTime[i] / roundtime) + killPercent );
		}
		
		entry->m_iWeaponID = i;
		weapons.AddToTail( entry );
	}

	weapons.Sort( &CGEStats::WeaponSort );

	// Only give them a fav weapon if they have a percentage
	fav.m_iPercentage = weapons[0]->m_iPercentage;
	if ( fav.m_iPercentage )
		fav.m_iWeaponID = weapons[0]->m_iWeaponID;
	else
		fav.m_iWeaponID = WEAPON_NONE;

#ifdef _DEBUG
	DevMsg( "%s's weapon stats:\n", pPlayer->GetPlayerName() );
	DevMsg( "Frags: %i, Roundtime: %0.2f\n", playerFrags, roundtime );
	for ( int i=0; i < WEAPON_MAX-2; i++ )
	{
		if ( weapons[i]->m_iPercentage )
			DevMsg( "%s : %i\n", WeaponIDToAlias( weapons[i]->m_iWeaponID ), weapons[i]->m_iPercentage );
	}
	DevMsg( "Favorite Weapon: %s\n", WeaponIDToAlias( fav.m_iWeaponID ) );
#endif

	weapons.PurgeAndDeleteElements();

	return true;
}
bool CGEStats::GetAwardWinner( int iAward, GEStatSort &winner )
{
	CUtlVector<GEStatSort*> stats;
	if ( GEMPRules()->GetNumActivePlayers() < 2 )
		return false;

	// Reset any previous inclinations
	winner.m_iAward = -1;
	winner.m_iStat = 0;

	CGEPlayer *pPlayer = NULL;
	// First parse out all the award to player information
	for ( int i=0; i < m_pPlayerStats.Count(); i++ )
	{
		// Don't try to give awards to invalid players
		pPlayer = m_pPlayerStats[i]->GetPlayer();
		if ( !pPlayer )
			continue;
		if ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR )
			continue;

		GEStatSort *entry = new GEStatSort;
		entry->idx = i;

		// If this is the last report, then take the match stats, average them over the rounds, and use that as our stat
		if ( GEGameplay()->IsInFinalIntermission() )
			entry->m_iStat = m_pPlayerStats[i]->GetMatchStat( iAward ) / m_iRoundCount;
		else
			entry->m_iStat = m_pPlayerStats[i]->GetRoundStat( iAward );

		stats.AddToTail( entry );
	}

	// Make sure after our checks we have at least two players to do awards for
	if ( stats.Count() < 2 )
		return false;

	float playerrat = (float)(stats.Count() + GE_STATS_PLAYERRATIO) / (float)stats.Count();

	if ( GetAwardSort(iAward) == GE_SORT_HIGH )
		stats.Sort( &CGEStats::StatSortHigh );
	else
	{
		stats.Sort( &CGEStats::StatSortLow );
		// Since we are sorting low we have to invert our player ratio
		playerrat = 1 / playerrat;
	}


	// Prevent divide by zero and inflation
	if ( stats[1]->m_iStat == 0 )
		stats[1]->m_iStat = 1;

	float statrat = (float)stats[0]->m_iStat / (float)stats[1]->m_iStat;
	
	// Low sort should have a ratio less than the inverted playerrat
	if ( GetAwardSort(iAward) == GE_SORT_HIGH ? statrat > playerrat : statrat < playerrat )
	{
		// Prevent divide by zero
		if ( statrat == 0 )
			statrat = 1;

		winner.idx = stats[0]->idx;
		winner.m_iStat = (GetAwardSort(iAward) == GE_SORT_HIGH ? statrat : 1/statrat) * 1000;  // 3 decimal precision
		winner.m_iAward = iAward;

		stats.PurgeAndDeleteElements();
		return true;
	}

	stats.PurgeAndDeleteElements();
	return false;
}