void UpdateStats( CBasePlayer *pPlayer ) { int i; int ammoCount[ MAX_AMMO_SLOTS ]; memcpy( ammoCount, pPlayer->m_rgAmmo, MAX_AMMO_SLOTS * sizeof(int) ); // Keep a running time, so the graph doesn't overlap if ( gpGlobals->time < gStats.lastGameTime ) // Changed level or died, don't b0rk { gStats.lastGameTime = gpGlobals->time; gStats.dataTime = gStats.gameTime; } gStats.gameTime += gpGlobals->time - gStats.lastGameTime; gStats.lastGameTime = gpGlobals->time; for (i = 0; i < MAX_ITEM_TYPES; i++) { CBasePlayerItem *p = pPlayer->m_rgpPlayerItems[i]; while (p) { ItemInfo II; memset(&II, 0, sizeof(II)); p->GetItemInfo(&II); int index = pPlayer->GetAmmoIndex(II.pszAmmo1); if ( index >= 0 ) ammoCount[ index ] += ((CBasePlayerWeapon *)p)->m_iClip; p = p->m_pNext; } } float ammo = 0; for (i = 1; i < MAX_AMMO_SLOTS; i++) { ammo += ammoCount[i] * AmmoDamage( CBasePlayerItem::AmmoInfoArray[i].pszName ); } float health = pPlayer->pev->health + pPlayer->pev->armorvalue * 2; // Armor is 2X health float ammoDelta = fabs( ammo - gStats.lastAmmo ); float healthDelta = fabs( health - gStats.lastHealth ); int forceWrite = 0; if ( health <= 0 && gStats.lastHealth > 0 ) forceWrite = 1; if ( (ammoDelta > AMMO_THRESHOLD || healthDelta > HEALTH_THRESHOLD) && !forceWrite ) { if ( gStats.nextOutputTime == 0 ) gStats.dataTime = gStats.gameTime; gStats.lastAmmo = ammo; gStats.lastHealth = health; gStats.nextOutputTime = gStats.gameTime + OUTPUT_LATENCY; } else if ( (gStats.nextOutputTime != 0 && gStats.nextOutputTime < gStats.gameTime) || forceWrite ) { UpdateStatsFile( gStats.dataTime, (char *)STRING(gpGlobals->mapname), health, ammo, (int)CVAR_GET_FLOAT("skill") ); gStats.lastAmmo = ammo; gStats.lastHealth = health; gStats.lastOutputTime = gStats.gameTime; gStats.nextOutputTime = 0; } }