#include "g_local.h" #define LOGGING_WEAPONS extern int borgQueenClientNum; /* ================= G_LogPrintf Print to the logfile with a time stamp if it is open ================= */ void QDECL G_LogPrintf( const char *fmt, ... ) { va_list argptr; char string[1024]; int min, tens, sec; sec = level.time / 1000; min = sec / 60; sec -= min * 60; tens = sec / 10; sec -= tens * 10; Com_sprintf( string, sizeof(string), "%3i:%i%i ", min, tens, sec ); va_start( argptr, fmt ); vsprintf( string +7 , fmt,argptr ); va_end( argptr ); if ( g_dedicated.integer ) { G_Printf( "%s", string + 7 ); } if ( !level.logFile ) { return; } trap_FS_Write( string, strlen( string ), level.logFile ); } /* ================ G_LogExit Append information about this game to the log file ================ */ void G_LogExit( const char *string ) { int i, numSorted; gclient_t *cl; G_LogPrintf( "Exit: %s\n", string ); level.intermissionQueued = level.time; // this will keep the clients from playing any voice sounds // that will get cut off when the queued intermission starts trap_SetConfigstring( CS_INTERMISSION, "1" ); // don't send more than 32 scores (FIXME?) numSorted = level.numConnectedClients; if ( numSorted > 32 ) { numSorted = 32; } if ( g_gametype.integer >= GT_TEAM ) { G_LogPrintf( "red:%i blue:%i\n", level.teamScores[TEAM_RED], level.teamScores[TEAM_BLUE] ); } for (i=0 ; i < numSorted ; i++) { int ping; cl = &level.clients[level.sortedClients[i]]; if ( cl->sess.sessionTeam == TEAM_SPECTATOR ) { continue; } if ( cl->pers.connected == CON_CONNECTING ) { continue; } ping = cl->ps.ping < 999 ? cl->ps.ping : 999; G_LogPrintf( "score: %i ping: %i client: %i %s\n", cl->ps.persistant[PERS_SCORE], ping, level.sortedClients[i], cl->pers.netname ); } } // Weapon statistic logging. // Nothing super-fancy here, I just want to keep track of, per player: // --hom many times a weapon/item is picked up // --how many times a weapon/item is used/fired // --the total damage done by that weapon // --the number of kills by that weapon // --the number of deaths while holding that weapon // --the time spent with each weapon // // Additionally, // --how many times each powerup or item is picked up #ifdef LOGGING_WEAPONS int G_WeaponLogPickups[MAX_CLIENTS][WP_NUM_WEAPONS]; int G_WeaponLogFired[MAX_CLIENTS][WP_NUM_WEAPONS]; int G_WeaponLogDamage[MAX_CLIENTS][MOD_MAX]; int G_WeaponLogKills[MAX_CLIENTS][MOD_MAX]; int G_WeaponLogDeaths[MAX_CLIENTS][WP_NUM_WEAPONS]; int G_WeaponLogFrags[MAX_CLIENTS][MAX_CLIENTS]; int G_WeaponLogTime[MAX_CLIENTS][WP_NUM_WEAPONS]; int G_WeaponLogLastTime[MAX_CLIENTS]; qboolean G_WeaponLogClientTouch[MAX_CLIENTS]; int G_WeaponLogPowerups[MAX_CLIENTS][HI_NUM_HOLDABLE]; int G_WeaponLogItems[MAX_CLIENTS][PW_NUM_POWERUPS]; // MOD-weapon mapping array. int weaponFromMOD[MOD_MAX] = { WP_NONE, // MOD_UNKNOWN, WP_NONE, // MOD_WATER, WP_NONE, // MOD_SLIME, WP_NONE, // MOD_LAVA, WP_NONE, // MOD_CRUSH, WP_NONE, // MOD_TELEFRAG, WP_NONE, // MOD_FALLING, WP_NONE, // MOD_SUICIDE, WP_NONE, // MOD_TARGET_LASER, WP_NONE, // MOD_TRIGGER_HURT, WP_PHASER, // MOD_PHASER, WP_PHASER, // MOD_PHASER_ALT, WP_COMPRESSION_RIFLE, // MOD_CRIFLE, WP_COMPRESSION_RIFLE, // MOD_CRIFLE_SPLASH, WP_COMPRESSION_RIFLE, // MOD_CRIFLE_ALT, WP_COMPRESSION_RIFLE, // MOD_CRIFLE_ALT_SPLASH, WP_NULL_HAND, // MOD_IMOD, WP_NULL_HAND, // MOD_IMOD_ALT, WP_COFFEE, // MOD_SCAVENGER, WP_COFFEE, // MOD_SCAVENGER_ALT, WP_COFFEE, // MOD_SCAVENGER_ALT_SPLASH, WP_DISRUPTOR, // MOD_STASIS, WP_DISRUPTOR, // MOD_STASIS_ALT, WP_GRENADE_LAUNCHER, // MOD_GRENADE, WP_GRENADE_LAUNCHER, // MOD_GRENADE_ALT, WP_GRENADE_LAUNCHER, // MOD_GRENADE_SPLASH, WP_GRENADE_LAUNCHER, // MOD_GRENADE_ALT_SPLASH, WP_TR116, // MOD_TETRION, WP_TR116, // MOD_TETRION_ALT, WP_DERMAL_REGEN, // MOD_DREADNOUGHT, WP_DERMAL_REGEN, // MOD_DREADNOUGHT_ALT, WP_QUANTUM_BURST, // MOD_QUANTUM, WP_QUANTUM_BURST, // MOD_QUANTUM_SPLASH, WP_QUANTUM_BURST, // MOD_QUANTUM_ALT, WP_QUANTUM_BURST, // MOD_QUANTUM_ALT_SPLASH, // careful!! don't assume that any given map entry refers to a weapon index. see //GetFavoriteWeaponForClient() as an example of what can go wrong. HI_DETPACK, // MOD_DETPACK, PW_FLASHLIGHT, // MOD_SEEKER //expansion pack WP_VOYAGER_HYPO, // MOD_KNOCKOUT, WP_TOOLKIT, // MOD_ASSIMILATE, WP_MEDKIT, // MOD_BORG, WP_MEDKIT, // MOD_BORG_ALT WP_NONE, // MOD_RESPAWN, WP_NONE, // MOD_EXPLOSION, WP_NONE, // MOD_FORCEFIELD WP_NONE, // MOD_FORCEDSUICIDE }; char *weaponNameFromIndex[WP_NUM_WEAPONS] = { "No Weapon", "Phaser", "Compression", "IMOD", "Scavenger", "Stasis", "Grenade", "Tetrion", "Quantum", "Dreadnought", "Hypo", "Assimilator", "Borg Weapon" }; extern char *modNames[]; #endif //LOGGING_WEAPONS /* ================= G_LogWeaponInit ================= */ void G_LogWeaponInit(void) { #ifdef LOGGING_WEAPONS memset(G_WeaponLogPickups, 0, sizeof(G_WeaponLogPickups)); memset(G_WeaponLogFired, 0, sizeof(G_WeaponLogFired)); memset(G_WeaponLogDamage, 0, sizeof(G_WeaponLogDamage)); memset(G_WeaponLogKills, 0, sizeof(G_WeaponLogKills)); memset(G_WeaponLogDeaths, 0, sizeof(G_WeaponLogDeaths)); memset(G_WeaponLogFrags, 0, sizeof(G_WeaponLogFrags)); memset(G_WeaponLogTime, 0, sizeof(G_WeaponLogTime)); memset(G_WeaponLogLastTime, 0, sizeof(G_WeaponLogLastTime)); memset(G_WeaponLogPowerups, 0, sizeof(G_WeaponLogPowerups)); memset(G_WeaponLogItems, 0, sizeof(G_WeaponLogItems)); #endif //LOGGING_WEAPONS } void QDECL G_LogWeaponPickup(int client, int weaponid) { #ifdef LOGGING_WEAPONS G_WeaponLogPickups[client][weaponid]++; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponFire(int client, int weaponid) { #ifdef LOGGING_WEAPONS int dur; G_WeaponLogFired[client][weaponid]++; dur = level.time - G_WeaponLogLastTime[client]; if (dur > 5000) // 5 second max. G_WeaponLogTime[client][weaponid] += 5000; else G_WeaponLogTime[client][weaponid] += dur; G_WeaponLogLastTime[client] = level.time; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponDamage(int client, int mod, int amount) { #ifdef LOGGING_WEAPONS if (client>=MAX_CLIENTS) return; G_WeaponLogDamage[client][mod] += amount; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponKill(int client, int mod) { #ifdef LOGGING_WEAPONS if (client>=MAX_CLIENTS) return; G_WeaponLogKills[client][mod]++; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponFrag(int attacker, int deadguy) { #ifdef LOGGING_WEAPONS if ( (attacker>=MAX_CLIENTS) || (deadguy>=MAX_CLIENTS) ) return; G_WeaponLogFrags[attacker][deadguy]++; G_WeaponLogClientTouch[attacker] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponDeath(int client, int weaponid) { #ifdef LOGGING_WEAPONS if (client>=MAX_CLIENTS) return; G_WeaponLogDeaths[client][weaponid]++; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponPowerup(int client, int powerupid) { #ifdef LOGGING_WEAPONS if (client>=MAX_CLIENTS) return; G_WeaponLogPowerups[client][powerupid]++; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } void QDECL G_LogWeaponItem(int client, int itemid) { #ifdef LOGGING_WEAPONS if (client>=MAX_CLIENTS) return; G_WeaponLogItems[client][itemid]++; G_WeaponLogClientTouch[client] = qtrue; #endif //_LOGGING_WEAPONS } // Run through each player. Print out: // -- Most commonly picked up weapon. // -- Weapon with which the most time was spent. // -- Weapon that was most often died with. // -- Damage type with which the most damage was done. // -- Damage type with the most kills. // -- Weapon with which the most damage was done. // -- Weapon with which the most damage was done per shot. // // For the whole game, print out: // -- Total pickups of each weapon. // -- Total time spent with each weapon. // -- Total damage done with each weapon. // -- Total damage done for each damage type. // -- Number of kills with each weapon. // -- Number of kills for each damage type. // -- Damage per shot with each weapon. // -- Number of deaths with each weapon. void G_LogWeaponOutput(void) { #if 0//LOGGING_WEAPONS int i,j,curwp; float pershot; fileHandle_t weaponfile; char string[1024]; int totalpickups[WP_NUM_WEAPONS]; int totaltime[WP_NUM_WEAPONS]; int totaldeaths[WP_NUM_WEAPONS]; int totaldamageMOD[MOD_MAX]; int totalkillsMOD[MOD_MAX]; int totaldamage[WP_NUM_WEAPONS]; int totalkills[WP_NUM_WEAPONS]; int totalshots[WP_NUM_WEAPONS]; int percharacter[WP_NUM_WEAPONS]; char info[1024]; char mapname[128]; char *nameptr, *unknownname=""; G_LogPrintf("*****************************Weapon Log:\n" ); memset(totalpickups, 0, sizeof(totalpickups)); memset(totaltime, 0, sizeof(totaltime)); memset(totaldeaths, 0, sizeof(totaldeaths)); memset(totaldamageMOD, 0, sizeof(totaldamageMOD)); memset(totalkillsMOD, 0, sizeof(totalkillsMOD)); memset(totaldamage, 0, sizeof(totaldamage)); memset(totalkills, 0, sizeof(totalkills)); memset(totalshots, 0, sizeof(totalshots)); for (i=0; i 0) { pershot = (float)(totaldamage[j])/(float)(totalshots[j]); } else { pershot = 0; } G_LogPrintf("%15s: Damage: %6d, Kills: %5d, Dmg per Shot: %f\n", weaponNameFromIndex[j], totaldamage[j], totalkills[j], pershot); } G_LogPrintf( "\n****Combat Data By Damage Type:\n" ); for (j=0; jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jpers.netname; } else { nameptr = unknownname; } trap_FS_Write(nameptr, strlen(nameptr), weaponfile); for (j=0;jinuse) continue; nShotsFired = player->client->ps.persistant[PERS_ACCURACY_SHOTS]; nShotsHit = player->client->ps.persistant[PERS_ACCURACY_HITS]; fAccuracyRatio = ( ((float)nShotsHit)/((float)nShotsFired) ); if (fAccuracyRatio > fBestRatio) { fBestRatio = fAccuracyRatio; nBestPlayer = i; } } if (-1 == nBestPlayer) { // huh? return qfalse; } if (nBestPlayer == ent->s.number) { tempEff = (int)(100*fBestRatio); if (tempEff > 50) { *efficiency = tempEff; return qtrue; } return qfalse; } #endif // LOGGING_WEAPONS return qfalse; }*/ // did this player earn the sharpshooter award? qboolean CalculateSharpshooter(gentity_t *ent, int *frags) { #ifdef LOGGING_WEAPONS int i = 0, nBestPlayer = -1, nKills = 0, nMostKills = 0, playTime = (level.time - ent->client->pers.enterTime)/60000; gentity_t *player = NULL; // if this guy didn't get one kill per minute, reject him right now if ( ((float)(G_WeaponLogKills[ent-g_entities][MOD_CRIFLE_ALT]))/((float)(playTime)) < 1.0 ) { return qfalse; } for (i = 0; i < g_maxclients.integer; i++) { nKills = 0; player = g_entities + i; if (!player->inuse) continue; nKills = G_WeaponLogKills[i][MOD_CRIFLE_ALT]; if (nKills > nMostKills) { nMostKills = nKills; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { *frags = nMostKills; return qtrue; } #endif // LOGGING_WEAPONS return qfalse; } // did this player earn the untouchable award? qboolean CalculateUntouchable(gentity_t *ent) { #ifdef LOGGING_WEAPONS int playTime; playTime = (level.time - ent->client->pers.enterTime)/60000; if ( g_pModAssimilation.integer && ent->client->ps.clientNum == borgQueenClientNum ) {//Borg queen can only be killed once anyway return qfalse; } //------------------------------------------------------ MUST HAVE ACHIEVED 2 KILLS PER MINUTE if ( ((float)ent->client->pers.teamState.frags)/((float)(playTime)) < 2.0 || playTime==0) return qfalse; //------------------------------------------------------ MUST HAVE ACHIEVED 2 KILLS PER MINUTE // if this guy was never killed... Award Away!!! if (ent->client->ps.persistant[PERS_KILLED]==0) return qtrue; #endif // LOGGING_WEAPONS return qfalse; } // did this player earn the logistics award? qboolean CalculateLogistics(gentity_t *ent, int *stuffUsed) { #ifdef LOGGING_WEAPONS int i = 0, j = 0, nBestPlayer = -1, nStuffUsed = 0, nMostStuffUsed = 0, nDifferent = 0, nMostDifferent = 0; gentity_t *player = NULL; for (i = 0; i < g_maxclients.integer; i++) { nStuffUsed = 0; nDifferent = 0; player = g_entities + i; if (!player->inuse) continue; for (j = HI_NONE+1; j < HI_NUM_HOLDABLE; j++) { if (G_WeaponLogPowerups[i][j]) { nDifferent++; } nStuffUsed += G_WeaponLogPowerups[i][j]; } for (j = PW_NONE+1; j < PW_NUM_POWERUPS; j++) { if (G_WeaponLogItems[i][j]) { nDifferent++; } nStuffUsed += G_WeaponLogItems[i][j]; } if ( (nDifferent >= 4) && (nDifferent >= nMostDifferent) ) { if (nStuffUsed > nMostStuffUsed) { nMostDifferent = nDifferent; nMostStuffUsed = nStuffUsed; nBestPlayer = i; } } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { *stuffUsed = nMostDifferent; return qtrue; } #endif // LOGGING_WEAPONS return qfalse; } // did this player earn the tactician award? qboolean CalculateTactician(gentity_t *ent, int *kills) { #ifdef LOGGING_WEAPONS int i = 0, nBestPlayer = -1, nKills = 0, nMostKills = 0; int person = 0, weapon = 0; gentity_t *player = NULL; int wasPickedUpBySomeone[WP_NUM_WEAPONS]; int killsWithWeapon[WP_NUM_WEAPONS]; int playTime = (level.time - ent->client->pers.enterTime)/60000; if ( g_pModDisintegration.integer ) {//duh, only 1 weapon return qfalse; } if ( g_pModAssimilation.integer && ent->client->ps.clientNum == borgQueenClientNum ) {//Borg queen has only 1 weapon return qfalse; } //------------------------------------------------------ MUST HAVE ACHIEVED 2 KILLS PER MINUTE if (playTime<0.3) return qfalse; if ( ((float)ent->client->pers.teamState.frags)/((float)(playTime)) < 2.0 ) return qfalse; //------------------------------------------------------ MUST HAVE ACHIEVED 2 KILLS PER MINUTE //------------------------------------------------------ FOR EVERY WEAPON, ADD UP TOTAL PICKUPS for (weapon = 0; weapon0) wasPickedUpBySomeone[weapon]++; } } //------------------------------------------------------ FOR EVERY WEAPON, ADD UP TOTAL PICKUPS //------------------------------------------------------ FOR EVERY PERSON, CHECK FOR CANDIDATE for (person=0; personinuse) continue; nKills = 0; // This Persons's Kills for (weapon=0; weapon0) ) { weapon++; nKills+=killsWithWeapon[weapon]; // Update the number of kills } // // At this point we have either successfully gone through every weapon on the map and saw it had // been used, or we found one that WAS on the map and was NOT used // // so we look to see if the weapon==Max (i.e. we used every one) and then we check to see // if we got the most kills out of anyone else who did this. // if (weapon>=WP_NUM_WEAPONS && nKills>nMostKills) { // WE ARE A TACTICION CANDIDATE nMostKills = nKills; nBestPlayer = person; } } //------------------------------------------------------ FOR EVERY PERSON, CHECK FOR CANDIDATE //Now, if we are the best player, return true and the number of kills we got if (nBestPlayer == ent->s.number) { *kills = nMostKills; return qtrue; } #endif // LOGGING_WEAPONS return qfalse; } // did this player earn the demolitionist award? qboolean CalculateDemolitionist(gentity_t *ent, int *kills) { #ifdef LOGGING_WEAPONS int i = 0, nBestPlayer = -1, nKills = 0, nMostKills = 0, playTime = (level.time - ent->client->pers.enterTime)/60000; gentity_t *player = NULL; for (i = 0; i < g_maxclients.integer; i++) { nKills = 0; player = g_entities + i; if (!player->inuse) continue; nKills = G_WeaponLogKills[i][MOD_GRENADE]; nKills += G_WeaponLogKills[i][MOD_GRENADE_SPLASH]; nKills += G_WeaponLogKills[i][MOD_GRENADE_ALT_SPLASH]; nKills += G_WeaponLogKills[i][MOD_QUANTUM]; nKills += G_WeaponLogKills[i][MOD_QUANTUM_SPLASH]; nKills += G_WeaponLogKills[i][MOD_QUANTUM_ALT]; nKills += G_WeaponLogKills[i][MOD_QUANTUM_ALT_SPLASH]; nKills += G_WeaponLogKills[i][MOD_DETPACK]; // if this guy didn't get two explosive kills per minute, reject him right now if ( ((float)nKills)/((float)(playTime)) < 2.0 ) { continue; } if (nKills > nMostKills) { nMostKills = nKills; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { *kills = nMostKills; return qtrue; } #endif // LOGGING_WEAPONS return qfalse; } int CalculateStreak(gentity_t *ent) { /*if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_CHAMPION) { return STREAK_CHAMPION; } if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_MASTER) { return STREAK_MASTER; } if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_EXPERT) { return STREAK_EXPERT; } if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_ACE) { return STREAK_ACE; }*/ return 0; } qboolean CalculateTeamMVP(gentity_t *ent) { int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ent->client->ps.persistant[PERS_TEAM]; gentity_t *player = NULL; for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team)) continue; nScore = player->client->ps.persistant[PERS_SCORE]; if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } qboolean CalculateTeamMVPByRank(gentity_t *ent) { playerState_t *ps = &ent->client->ps; int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ps->persistant[PERS_RANK]+1; qboolean bTied = (team == 3); gentity_t *player = NULL; for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse) continue; if (!bTied) { if (ps->persistant[PERS_TEAM] != team) { continue; } } nScore = ps->persistant[PERS_SCORE]; if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } qboolean CalculateTeamDefender(gentity_t *ent) { int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ent->client->ps.persistant[PERS_TEAM]; gentity_t *player = NULL; /* if (CalculateTeamMVP(ent)) { return qfalse; } */ for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team)) continue; nScore = player->client->pers.teamState.basedefense; if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } qboolean CalculateTeamWarrior(gentity_t *ent) { int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ent->client->ps.persistant[PERS_TEAM]; gentity_t *player = NULL; /* if (CalculateTeamMVP(ent) || CalculateTeamDefender(ent)) { return qfalse; } */ for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team)) continue; nScore = player->client->pers.teamState.frags; if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } qboolean CalculateTeamCarrier(gentity_t *ent) { int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ent->client->ps.persistant[PERS_TEAM]; gentity_t *player = NULL; /* if (CalculateTeamMVP(ent) || CalculateTeamDefender(ent) || CalculateTeamWarrior(ent)) { return qfalse; } */ for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team)) continue; nScore = player->client->pers.teamState.captures; if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } qboolean CalculateTeamInterceptor(gentity_t *ent) { int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ent->client->ps.persistant[PERS_TEAM]; gentity_t *player = NULL; /* if (CalculateTeamMVP(ent) || CalculateTeamDefender(ent) || CalculateTeamWarrior(ent) || CalculateTeamCarrier(ent)) { return qfalse; } */ for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team)) continue; nScore = player->client->pers.teamState.flagrecovery; nScore += player->client->pers.teamState.fragcarrier; if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } qboolean CalculateTeamRedShirt(gentity_t *ent) { int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0, team = ent->client->ps.persistant[PERS_TEAM]; gentity_t *player = NULL; /* if (CalculateTeamMVP(ent) || CalculateTeamDefender(ent) || CalculateTeamWarrior(ent) || CalculateTeamCarrier(ent) || CalculateTeamInterceptor(ent)) { return qfalse; } */ for (i = 0; i < g_maxclients.integer; i++) { nScore = 0; player = g_entities + i; if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team)) continue; nScore = player->client->ps.persistant[PERS_KILLED]; nScore -= player->client->pers.teamState.suicides; // suicides don't count, you big cheater. if (nScore > nHighestScore) { nHighestScore = nScore; nBestPlayer = i; } } if (-1 == nBestPlayer) { return qfalse; } if (nBestPlayer == ent->s.number) { return qtrue; } return qfalse; } int CalculateTeamAward(gentity_t *ent) { int teamAwards = 0; if (CalculateTeamMVP(ent)) { teamAwards |= (1<inuse) continue; // // kef -- heh. // // if (strcmp("JaxxonPhred", ent->client->pers.netname)) // { // continue; // } /*CalculateEfficiency(ent, &efficiency); if (!CalculateSharpshooter(ent, &frags) || !CalculateUntouchable(ent) || (CalculateStreak(ent) < STREAK_CHAMPION) || (efficiency < 75)) { continue; }*/ return qtrue; } return qfalse; } void CalculateAwards(gentity_t *ent, char *msg) { #ifdef LOGGING_WEAPONS char buf1[AWARDS_MSG_LENGTH], buf2[AWARDS_MSG_LENGTH]; int awardFlags = 0, /*efficiency = 0,*/ stuffUsed = 0, kills = 0, streak = 0, teamAwards = 0; memset(buf1, 0, AWARDS_MSG_LENGTH); memset(buf2, 0, AWARDS_MSG_LENGTH); /*if (CalculateEfficiency(ent, &efficiency)) { awardFlags |= (1<= GT_TEAM) { teamAwards = CalculateTeamAward(ent); if (teamAwards) { awardFlags |= (1<= MAX_CLIENTS)) { return 0; } for (i = 0; i < MAX_CLIENTS; i++) { if (G_WeaponLogFrags[i][nClient] > nMostDeaths) { nMostDeaths = G_WeaponLogFrags[i][nClient]; } } return nMostDeaths; } int GetMaxKillsForClient(int nClient) { int i = 0, nMostKills = 0; if ((nClient < 0) || (nClient >= MAX_CLIENTS)) { return 0; } for (i = 0; i < MAX_CLIENTS; i++) { if (G_WeaponLogFrags[nClient][i] > nMostKills) { nMostKills = G_WeaponLogFrags[nClient][i]; } } return nMostKills; } int GetFavoriteTargetForClient(int nClient) { int i = 0, nMostKills = 0, nFavoriteTarget = -1; if ((nClient < 0) || (nClient >= MAX_CLIENTS)) { return 0; } for (i = 0; i < MAX_CLIENTS; i++) { if (G_WeaponLogFrags[nClient][i] > nMostKills) { nMostKills = G_WeaponLogFrags[nClient][i]; nFavoriteTarget = i; } } return nFavoriteTarget; } int GetWorstEnemyForClient(int nClient) { int i = 0, nMostDeaths = 0, nWorstEnemy = -1; if ((nClient < 0) || (nClient >= MAX_CLIENTS)) { return 0; } for (i = 0; i < MAX_CLIENTS; i++) { // If there is a tie for most deaths, we want to choose anybody else // over the client... I.E. Most deaths should not tie with yourself and // have yourself show up... if ( G_WeaponLogFrags[i][nClient] > nMostDeaths || (G_WeaponLogFrags[i][nClient]== nMostDeaths && i!=nClient && nMostDeaths!=0) ) { nMostDeaths = G_WeaponLogFrags[i][nClient]; nWorstEnemy = i; } } return nWorstEnemy; } int GetFavoriteWeaponForClient(int nClient) { int i = 0, nMostKills = 0, fav=0, weapon=WP_PHASER; int killsWithWeapon[WP_NUM_WEAPONS]; // First thing we need to do is cycle through all the MOD types and convert // number of kills to a single weapon. //---------------------------------------------------------------- for (weapon=0; weaponnMostKills) { nMostKills = killsWithWeapon[weapon]; fav = weapon; } } return fav; } // kef -- if a client leaves the game, clear out all counters he may have set void QDECL G_ClearClientLog(int client) { int i = 0; for (i = 0; i < WP_NUM_WEAPONS; i++) { G_WeaponLogPickups[client][i] = 0; } for (i = 0; i < WP_NUM_WEAPONS; i++) { G_WeaponLogFired[client][i] = 0; } for (i = 0; i < MOD_MAX; i++) { G_WeaponLogDamage[client][i] = 0; } for (i = 0; i < MOD_MAX; i++) { G_WeaponLogKills[client][i] = 0; } for (i = 0; i < WP_NUM_WEAPONS; i++) { G_WeaponLogDeaths[client][i] = 0; } for (i = 0; i < MAX_CLIENTS; i++) { G_WeaponLogFrags[client][i] = 0; } for (i = 0; i < MAX_CLIENTS; i++) { G_WeaponLogFrags[i][client] = 0; } for (i = 0; i < WP_NUM_WEAPONS; i++) { G_WeaponLogTime[client][i] = 0; } G_WeaponLogLastTime[client] = 0; G_WeaponLogClientTouch[client] = qfalse; for (i = 0; i < HI_NUM_HOLDABLE; i++) { G_WeaponLogPowerups[client][i] = 0; } for (i = 0; i < PW_NUM_POWERUPS; i++) { G_WeaponLogItems[client][i] = 0; } }