//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // // $NoKeywords: $ //============================================================================= #include "extdll.h" #include "util.h" #include "cbase.h" #include "player.h" #include "trains.h" #include "nodes.h" #include "weapons.h" #include "soundent.h" #include "monsters.h" #include "../engine/shake.h" #include "decals.h" #include "gamerules.h" float AmmoDamage( const char *pName ) { if( !pName ) return 0; if( !strcmp( pName, "9mm" ) ) return gSkillData.plrDmg9MM; if( !strcmp( pName, "357" ) ) return gSkillData.plrDmg357; if( !strcmp( pName, "ARgrenades" ) ) return gSkillData.plrDmgM203Grenade; if( !strcmp( pName, "buckshot" ) ) return gSkillData.plrDmgBuckshot; if( !strcmp( pName, "bolts") ) return gSkillData.plrDmgCrossbowMonster; if( !strcmp( pName, "rockets") ) return gSkillData.plrDmgRPG; if( !strcmp( pName, "uranium") ) return gSkillData.plrDmgGauss; if( !strcmp( pName, "Hand Grenade") ) return gSkillData.plrDmgHandGrenade; if( !strcmp( pName, "Satchel Charge") ) return gSkillData.plrDmgSatchel; if( !strcmp( pName, "Trip Mine") ) return gSkillData.plrDmgTripmine; return 0; } void UpdateStatsFile( float dataTime, const char *pMapname, float health, float ammo, int skillLevel ) { FILE *fp; fp = fopen( "stats.txt", "a" ); if( !fp ) return; fprintf( fp, "%6.2f, %6.2f, %6.2f, %s, %2d\n", dataTime, health, ammo, pMapname, skillLevel ); fclose( fp ); } #define AMMO_THRESHOLD 10 // This much ammo goes by before it is "interesting" #define HEALTH_THRESHOLD 10 // Same for health #define OUTPUT_LATENCY 3 // This many seconds for ammo/health to settle typedef struct { int lastAmmo; float lastHealth; float lastOutputTime; // NOTE: These times are in "game" time -- a running total of elapsed time since the game started float nextOutputTime; float dataTime; float gameTime; float lastGameTime; } TESTSTATS; TESTSTATS gStats = { 0, 0, 0, 0, 0, 0, 0 }; 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 = {0}; 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, STRING( gpGlobals->mapname ), health, ammo, (int)CVAR_GET_FLOAT( "skill" ) ); gStats.lastAmmo = ammo; gStats.lastHealth = health; gStats.lastOutputTime = gStats.gameTime; gStats.nextOutputTime = 0; } } void InitStats( CBasePlayer *pPlayer ) { gStats.lastGameTime = gpGlobals->time; // Fixup stats time }