00001 #include "g_local.h"
00002
00003 #define LOGGING_WEAPONS
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef LOGGING_WEAPONS
00019 int G_WeaponLogPickups[MAX_CLIENTS][WP_NUM_WEAPONS];
00020 int G_WeaponLogFired[MAX_CLIENTS][WP_NUM_WEAPONS];
00021 int G_WeaponLogDamage[MAX_CLIENTS][MOD_MAX];
00022 int G_WeaponLogKills[MAX_CLIENTS][MOD_MAX];
00023 int G_WeaponLogDeaths[MAX_CLIENTS][WP_NUM_WEAPONS];
00024 int G_WeaponLogFrags[MAX_CLIENTS][MAX_CLIENTS];
00025 int G_WeaponLogTime[MAX_CLIENTS][WP_NUM_WEAPONS];
00026 int G_WeaponLogLastTime[MAX_CLIENTS];
00027 qboolean G_WeaponLogClientTouch[MAX_CLIENTS];
00028 int G_WeaponLogPowerups[MAX_CLIENTS][HI_NUM_HOLDABLE];
00029 int G_WeaponLogItems[MAX_CLIENTS][PW_NUM_POWERUPS];
00030
00031 extern vmCvar_t g_statLog;
00032 extern vmCvar_t g_statLogFile;
00033
00034
00035 int weaponFromMOD[MOD_MAX] =
00036 {
00037 WP_NONE,
00038 WP_STUN_BATON,
00039 WP_MELEE,
00040 WP_SABER,
00041 WP_BRYAR_PISTOL,
00042 WP_BRYAR_PISTOL,
00043 WP_BLASTER,
00044 WP_TURRET,
00045 WP_DISRUPTOR,
00046 WP_DISRUPTOR,
00047 WP_DISRUPTOR,
00048 WP_BOWCASTER,
00049 WP_REPEATER,
00050 WP_REPEATER,
00051 WP_REPEATER,
00052 WP_DEMP2,
00053 WP_DEMP2,
00054 WP_FLECHETTE,
00055 WP_FLECHETTE,
00056 WP_ROCKET_LAUNCHER,
00057 WP_ROCKET_LAUNCHER,
00058 WP_ROCKET_LAUNCHER,
00059 WP_ROCKET_LAUNCHER,
00060 WP_THERMAL,
00061 WP_THERMAL,
00062 WP_TRIP_MINE,
00063 WP_TRIP_MINE,
00064 WP_DET_PACK,
00065 WP_NONE,
00066 WP_NONE,
00067 WP_NONE,
00068 WP_NONE,
00069 WP_NONE,
00070 WP_NONE,
00071 WP_NONE,
00072 WP_NONE,
00073 WP_NONE,
00074 WP_NONE,
00075 WP_NONE,
00076 };
00077
00078 char *weaponNameFromIndex[WP_NUM_WEAPONS] =
00079 {
00080 "No Weapon",
00081 "Stun Baton",
00082 "Saber",
00083 "Bryar Pistol",
00084 "Blaster",
00085 "Disruptor",
00086 "Bowcaster",
00087 "Repeater",
00088 "Demp2",
00089 "Flechette",
00090 "Rocket Launcher",
00091 "Thermal",
00092 "Tripmine",
00093 "Detpack",
00094 "Emplaced gun",
00095 "Turret"
00096 };
00097
00098 extern char *modNames[];
00099
00100 #endif //LOGGING_WEAPONS
00101
00102
00103
00104
00105
00106
00107 void G_LogWeaponInit(void) {
00108 #ifdef LOGGING_WEAPONS
00109 memset(G_WeaponLogPickups, 0, sizeof(G_WeaponLogPickups));
00110 memset(G_WeaponLogFired, 0, sizeof(G_WeaponLogFired));
00111 memset(G_WeaponLogDamage, 0, sizeof(G_WeaponLogDamage));
00112 memset(G_WeaponLogKills, 0, sizeof(G_WeaponLogKills));
00113 memset(G_WeaponLogDeaths, 0, sizeof(G_WeaponLogDeaths));
00114 memset(G_WeaponLogFrags, 0, sizeof(G_WeaponLogFrags));
00115 memset(G_WeaponLogTime, 0, sizeof(G_WeaponLogTime));
00116 memset(G_WeaponLogLastTime, 0, sizeof(G_WeaponLogLastTime));
00117 memset(G_WeaponLogPowerups, 0, sizeof(G_WeaponLogPowerups));
00118 memset(G_WeaponLogItems, 0, sizeof(G_WeaponLogItems));
00119 #endif //LOGGING_WEAPONS
00120 }
00121
00122 void QDECL G_LogWeaponPickup(int client, int weaponid)
00123 {
00124 #ifdef LOGGING_WEAPONS
00125 G_WeaponLogPickups[client][weaponid]++;
00126 G_WeaponLogClientTouch[client] = qtrue;
00127 #endif //_LOGGING_WEAPONS
00128 }
00129
00130 void QDECL G_LogWeaponFire(int client, int weaponid)
00131 {
00132 #ifdef LOGGING_WEAPONS
00133 int dur;
00134
00135 G_WeaponLogFired[client][weaponid]++;
00136 dur = level.time - G_WeaponLogLastTime[client];
00137 if (dur > 5000)
00138 G_WeaponLogTime[client][weaponid] += 5000;
00139 else
00140 G_WeaponLogTime[client][weaponid] += dur;
00141 G_WeaponLogLastTime[client] = level.time;
00142 G_WeaponLogClientTouch[client] = qtrue;
00143 #endif //_LOGGING_WEAPONS
00144 }
00145
00146 void QDECL G_LogWeaponDamage(int client, int mod, int amount)
00147 {
00148 #ifdef LOGGING_WEAPONS
00149 if (client>=MAX_CLIENTS)
00150 return;
00151 G_WeaponLogDamage[client][mod] += amount;
00152 G_WeaponLogClientTouch[client] = qtrue;
00153 #endif //_LOGGING_WEAPONS
00154 }
00155
00156 void QDECL G_LogWeaponKill(int client, int mod)
00157 {
00158 #ifdef LOGGING_WEAPONS
00159 if (client>=MAX_CLIENTS)
00160 return;
00161 G_WeaponLogKills[client][mod]++;
00162 G_WeaponLogClientTouch[client] = qtrue;
00163 #endif //_LOGGING_WEAPONS
00164 }
00165
00166 void QDECL G_LogWeaponFrag(int attacker, int deadguy)
00167 {
00168 #ifdef LOGGING_WEAPONS
00169 if ( (attacker>=MAX_CLIENTS) || (deadguy>=MAX_CLIENTS) )
00170 return;
00171 G_WeaponLogFrags[attacker][deadguy]++;
00172 G_WeaponLogClientTouch[attacker] = qtrue;
00173 #endif //_LOGGING_WEAPONS
00174 }
00175
00176 void QDECL G_LogWeaponDeath(int client, int weaponid)
00177 {
00178 #ifdef LOGGING_WEAPONS
00179 if (client>=MAX_CLIENTS)
00180 return;
00181 G_WeaponLogDeaths[client][weaponid]++;
00182 G_WeaponLogClientTouch[client] = qtrue;
00183 #endif //_LOGGING_WEAPONS
00184 }
00185
00186 void QDECL G_LogWeaponPowerup(int client, int powerupid)
00187 {
00188 #ifdef LOGGING_WEAPONS
00189 if (client>=MAX_CLIENTS)
00190 return;
00191 G_WeaponLogPowerups[client][powerupid]++;
00192 G_WeaponLogClientTouch[client] = qtrue;
00193 #endif //_LOGGING_WEAPONS
00194 }
00195
00196 void QDECL G_LogWeaponItem(int client, int itemid)
00197 {
00198 #ifdef LOGGING_WEAPONS
00199 if (client>=MAX_CLIENTS)
00200 return;
00201 G_WeaponLogItems[client][itemid]++;
00202 G_WeaponLogClientTouch[client] = qtrue;
00203 #endif //_LOGGING_WEAPONS
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 void G_LogWeaponOutput(void)
00227 {
00228 #ifdef LOGGING_WEAPONS
00229 int i,j,curwp;
00230 float pershot;
00231 fileHandle_t weaponfile;
00232 char string[1024];
00233
00234 int totalpickups[WP_NUM_WEAPONS];
00235 int totaltime[WP_NUM_WEAPONS];
00236 int totaldeaths[WP_NUM_WEAPONS];
00237 int totaldamageMOD[MOD_MAX];
00238 int totalkillsMOD[MOD_MAX];
00239 int totaldamage[WP_NUM_WEAPONS];
00240 int totalkills[WP_NUM_WEAPONS];
00241 int totalshots[WP_NUM_WEAPONS];
00242 int percharacter[WP_NUM_WEAPONS];
00243 char info[1024];
00244 char mapname[128];
00245 char *nameptr, *unknownname="<Unknown>";
00246
00247 if (!g_statLog.integer)
00248 {
00249 return;
00250 }
00251
00252 G_LogPrintf("*****************************Weapon Log:\n" );
00253
00254 memset(totalpickups, 0, sizeof(totalpickups));
00255 memset(totaltime, 0, sizeof(totaltime));
00256 memset(totaldeaths, 0, sizeof(totaldeaths));
00257 memset(totaldamageMOD, 0, sizeof(totaldamageMOD));
00258 memset(totalkillsMOD, 0, sizeof(totalkillsMOD));
00259 memset(totaldamage, 0, sizeof(totaldamage));
00260 memset(totalkills, 0, sizeof(totalkills));
00261 memset(totalshots, 0, sizeof(totalshots));
00262
00263 for (i=0; i<MAX_CLIENTS; i++)
00264 {
00265 if (G_WeaponLogClientTouch[i])
00266 {
00267 for (j=0;j<WP_NUM_WEAPONS;j++)
00268 {
00269 totalpickups[j] += G_WeaponLogPickups[i][j];
00270 totaltime[j] += G_WeaponLogTime[i][j];
00271 totaldeaths[j] += G_WeaponLogDeaths[i][j];
00272 totalshots[j] += G_WeaponLogFired[i][j];
00273 }
00274
00275 for (j=0;j<MOD_MAX;j++)
00276 {
00277 totaldamageMOD[j] += G_WeaponLogDamage[i][j];
00278 totalkillsMOD[j] += G_WeaponLogKills[i][j];
00279 }
00280 }
00281 }
00282
00283
00284 for (j=0; j<MOD_MAX; j++)
00285 {
00286 if (j <= MOD_SENTRY)
00287 {
00288 curwp = weaponFromMOD[j];
00289 totaldamage[curwp] += totaldamageMOD[j];
00290 totalkills[curwp] += totalkillsMOD[j];
00291 }
00292 }
00293
00294 G_LogPrintf( "\n****Data by Weapon:\n" );
00295 for (j=0; j<WP_NUM_WEAPONS; j++)
00296 {
00297 G_LogPrintf("%15s: Pickups: %4d, Time: %5d, Deaths: %5d\n",
00298 weaponNameFromIndex[j], totalpickups[j], (int)(totaltime[j]/1000), totaldeaths[j]);
00299 }
00300
00301 G_LogPrintf( "\n****Combat Data by Weapon:\n" );
00302 for (j=0; j<WP_NUM_WEAPONS; j++)
00303 {
00304 if (totalshots[j] > 0)
00305 {
00306 pershot = (float)(totaldamage[j])/(float)(totalshots[j]);
00307 }
00308 else
00309 {
00310 pershot = 0;
00311 }
00312 G_LogPrintf("%15s: Damage: %6d, Kills: %5d, Dmg per Shot: %f\n",
00313 weaponNameFromIndex[j], totaldamage[j], totalkills[j], pershot);
00314 }
00315
00316 G_LogPrintf( "\n****Combat Data By Damage Type:\n" );
00317 for (j=0; j<MOD_MAX; j++)
00318 {
00319 G_LogPrintf("%25s: Damage: %6d, Kills: %5d\n",
00320 modNames[j], totaldamageMOD[j], totalkillsMOD[j]);
00321 }
00322
00323 G_LogPrintf("\n");
00324
00325
00326
00327
00328 trap_FS_FOpenFile( g_statLogFile.string, &weaponfile, FS_APPEND );
00329 if (!weaponfile) {
00330 return;
00331 }
00332
00333
00334 trap_GetServerinfo(info, sizeof(info));
00335 strncpy(mapname, Info_ValueForKey( info, "mapname" ), sizeof(mapname)-1);
00336 mapname[sizeof(mapname)-1] = '\0';
00337
00338 Com_sprintf(string, sizeof(string), "\n\n\nLevel:\t%s\n\n\n", mapname);
00339 trap_FS_Write( string, strlen( string ), weaponfile);
00340
00341
00342
00343
00344
00345 Com_sprintf(string, sizeof(string), "Weapon Pickups per Player:\n\n");
00346 trap_FS_Write( string, strlen( string ), weaponfile);
00347
00348 Com_sprintf(string, sizeof(string), "Player");
00349 trap_FS_Write(string, strlen(string), weaponfile);
00350
00351 for (j=0; j<WP_NUM_WEAPONS; j++)
00352 {
00353 Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
00354 trap_FS_Write(string, strlen(string), weaponfile);
00355 }
00356 Com_sprintf(string, sizeof(string), "\n");
00357 trap_FS_Write(string, strlen(string), weaponfile);
00358
00359
00360 for (i=0; i<MAX_CLIENTS; i++)
00361 {
00362 if (G_WeaponLogClientTouch[i])
00363 {
00364 if ( g_entities[i].client )
00365 {
00366 nameptr = g_entities[i].client->pers.netname;
00367 }
00368 else
00369 {
00370 nameptr = unknownname;
00371 }
00372 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00373
00374 for (j=0;j<WP_NUM_WEAPONS;j++)
00375 {
00376 Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogPickups[i][j]);
00377 trap_FS_Write(string, strlen(string), weaponfile);
00378 }
00379
00380 Com_sprintf(string, sizeof(string), "\n");
00381 trap_FS_Write(string, strlen(string), weaponfile);
00382 }
00383 }
00384
00385
00386 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00387 trap_FS_Write(string, strlen(string), weaponfile);
00388
00389 for (j=0;j<WP_NUM_WEAPONS;j++)
00390 {
00391 Com_sprintf(string, sizeof(string), "\t%d", totalpickups[j]);
00392 trap_FS_Write(string, strlen(string), weaponfile);
00393 }
00394
00395 Com_sprintf(string, sizeof(string), "\n\n\n");
00396 trap_FS_Write(string, strlen(string), weaponfile);
00397
00398
00399
00400 Com_sprintf(string, sizeof(string), "Weapon Shots per Player:\n\n");
00401 trap_FS_Write( string, strlen( string ), weaponfile);
00402
00403 Com_sprintf(string, sizeof(string), "Player");
00404 trap_FS_Write(string, strlen(string), weaponfile);
00405
00406 for (j=0; j<WP_NUM_WEAPONS; j++)
00407 {
00408 Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
00409 trap_FS_Write(string, strlen(string), weaponfile);
00410 }
00411 Com_sprintf(string, sizeof(string), "\n");
00412 trap_FS_Write(string, strlen(string), weaponfile);
00413
00414
00415 for (i=0; i<MAX_CLIENTS; i++)
00416 {
00417 if (G_WeaponLogClientTouch[i])
00418 {
00419 if ( g_entities[i].client )
00420 {
00421 nameptr = g_entities[i].client->pers.netname;
00422 }
00423 else
00424 {
00425 nameptr = unknownname;
00426 }
00427 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00428
00429 for (j=0;j<WP_NUM_WEAPONS;j++)
00430 {
00431 Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogFired[i][j]);
00432 trap_FS_Write(string, strlen(string), weaponfile);
00433 }
00434
00435 Com_sprintf(string, sizeof(string), "\n");
00436 trap_FS_Write(string, strlen(string), weaponfile);
00437 }
00438 }
00439
00440
00441 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00442 trap_FS_Write(string, strlen(string), weaponfile);
00443
00444 for (j=0;j<WP_NUM_WEAPONS;j++)
00445 {
00446 Com_sprintf(string, sizeof(string), "\t%d", totalshots[j]);
00447 trap_FS_Write(string, strlen(string), weaponfile);
00448 }
00449
00450 Com_sprintf(string, sizeof(string), "\n\n\n");
00451 trap_FS_Write(string, strlen(string), weaponfile);
00452
00453
00454
00455 Com_sprintf(string, sizeof(string), "Weapon Use Time per Player:\n\n");
00456 trap_FS_Write( string, strlen( string ), weaponfile);
00457
00458 Com_sprintf(string, sizeof(string), "Player");
00459 trap_FS_Write(string, strlen(string), weaponfile);
00460
00461 for (j=0; j<WP_NUM_WEAPONS; j++)
00462 {
00463 Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
00464 trap_FS_Write(string, strlen(string), weaponfile);
00465 }
00466 Com_sprintf(string, sizeof(string), "\n");
00467 trap_FS_Write(string, strlen(string), weaponfile);
00468
00469
00470 for (i=0; i<MAX_CLIENTS; i++)
00471 {
00472 if (G_WeaponLogClientTouch[i])
00473 {
00474 if ( g_entities[i].client )
00475 {
00476 nameptr = g_entities[i].client->pers.netname;
00477 }
00478 else
00479 {
00480 nameptr = unknownname;
00481 }
00482 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00483
00484 for (j=0;j<WP_NUM_WEAPONS;j++)
00485 {
00486 Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogTime[i][j]);
00487 trap_FS_Write(string, strlen(string), weaponfile);
00488 }
00489
00490 Com_sprintf(string, sizeof(string), "\n");
00491 trap_FS_Write(string, strlen(string), weaponfile);
00492 }
00493 }
00494
00495
00496 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00497 trap_FS_Write(string, strlen(string), weaponfile);
00498
00499 for (j=0;j<WP_NUM_WEAPONS;j++)
00500 {
00501 Com_sprintf(string, sizeof(string), "\t%d", totaltime[j]);
00502 trap_FS_Write(string, strlen(string), weaponfile);
00503 }
00504
00505 Com_sprintf(string, sizeof(string), "\n\n\n");
00506 trap_FS_Write(string, strlen(string), weaponfile);
00507
00508
00509
00510
00511 Com_sprintf(string, sizeof(string), "Weapon Deaths per Player:\n\n");
00512 trap_FS_Write( string, strlen( string ), weaponfile);
00513
00514 Com_sprintf(string, sizeof(string), "Player");
00515 trap_FS_Write(string, strlen(string), weaponfile);
00516
00517 for (j=0; j<WP_NUM_WEAPONS; j++)
00518 {
00519 Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
00520 trap_FS_Write(string, strlen(string), weaponfile);
00521 }
00522 Com_sprintf(string, sizeof(string), "\n");
00523 trap_FS_Write(string, strlen(string), weaponfile);
00524
00525
00526 for (i=0; i<MAX_CLIENTS; i++)
00527 {
00528 if (G_WeaponLogClientTouch[i])
00529 {
00530 if ( g_entities[i].client )
00531 {
00532 nameptr = g_entities[i].client->pers.netname;
00533 }
00534 else
00535 {
00536 nameptr = unknownname;
00537 }
00538 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00539
00540 for (j=0;j<WP_NUM_WEAPONS;j++)
00541 {
00542 Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogDeaths[i][j]);
00543 trap_FS_Write(string, strlen(string), weaponfile);
00544 }
00545
00546 Com_sprintf(string, sizeof(string), "\n");
00547 trap_FS_Write(string, strlen(string), weaponfile);
00548 }
00549 }
00550
00551
00552 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00553 trap_FS_Write(string, strlen(string), weaponfile);
00554
00555 for (j=0;j<WP_NUM_WEAPONS;j++)
00556 {
00557 Com_sprintf(string, sizeof(string), "\t%d", totaldeaths[j]);
00558 trap_FS_Write(string, strlen(string), weaponfile);
00559 }
00560
00561 Com_sprintf(string, sizeof(string), "\n\n\n");
00562 trap_FS_Write(string, strlen(string), weaponfile);
00563
00564
00565
00566
00567
00568
00569 Com_sprintf(string, sizeof(string), "Weapon Damage per Player:\n\n");
00570 trap_FS_Write( string, strlen( string ), weaponfile);
00571
00572 Com_sprintf(string, sizeof(string), "Player");
00573 trap_FS_Write(string, strlen(string), weaponfile);
00574
00575 for (j=0; j<WP_NUM_WEAPONS; j++)
00576 {
00577 Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
00578 trap_FS_Write(string, strlen(string), weaponfile);
00579 }
00580 Com_sprintf(string, sizeof(string), "\n");
00581 trap_FS_Write(string, strlen(string), weaponfile);
00582
00583
00584 for (i=0; i<MAX_CLIENTS; i++)
00585 {
00586 if (G_WeaponLogClientTouch[i])
00587 {
00588
00589
00590 memset(percharacter, 0, sizeof(percharacter));
00591 for (j=0; j<MOD_MAX; j++)
00592 {
00593 if (j <= MOD_SENTRY)
00594 {
00595 curwp = weaponFromMOD[j];
00596 percharacter[curwp] += G_WeaponLogDamage[i][j];
00597 }
00598 }
00599
00600 if ( g_entities[i].client )
00601 {
00602 nameptr = g_entities[i].client->pers.netname;
00603 }
00604 else
00605 {
00606 nameptr = unknownname;
00607 }
00608 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00609
00610 for (j=0;j<WP_NUM_WEAPONS;j++)
00611 {
00612 Com_sprintf(string, sizeof(string), "\t%d", percharacter[j]);
00613 trap_FS_Write(string, strlen(string), weaponfile);
00614 }
00615
00616 Com_sprintf(string, sizeof(string), "\n");
00617 trap_FS_Write(string, strlen(string), weaponfile);
00618 }
00619 }
00620
00621
00622 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00623 trap_FS_Write(string, strlen(string), weaponfile);
00624
00625 for (j=0;j<WP_NUM_WEAPONS;j++)
00626 {
00627 Com_sprintf(string, sizeof(string), "\t%d", totaldamage[j]);
00628 trap_FS_Write(string, strlen(string), weaponfile);
00629 }
00630
00631 Com_sprintf(string, sizeof(string), "\n\n\n");
00632 trap_FS_Write(string, strlen(string), weaponfile);
00633
00634
00635
00636
00637
00638 Com_sprintf(string, sizeof(string), "Weapon Kills per Player:\n\n");
00639 trap_FS_Write( string, strlen( string ), weaponfile);
00640
00641 Com_sprintf(string, sizeof(string), "Player");
00642 trap_FS_Write(string, strlen(string), weaponfile);
00643
00644 for (j=0; j<WP_NUM_WEAPONS; j++)
00645 {
00646 Com_sprintf(string, sizeof(string), "\t%s", weaponNameFromIndex[j]);
00647 trap_FS_Write(string, strlen(string), weaponfile);
00648 }
00649 Com_sprintf(string, sizeof(string), "\n");
00650 trap_FS_Write(string, strlen(string), weaponfile);
00651
00652
00653 for (i=0; i<MAX_CLIENTS; i++)
00654 {
00655 if (G_WeaponLogClientTouch[i])
00656 {
00657
00658
00659 memset(percharacter, 0, sizeof(percharacter));
00660 for (j=0; j<MOD_MAX; j++)
00661 {
00662 if (j <= MOD_SENTRY)
00663 {
00664 curwp = weaponFromMOD[j];
00665 percharacter[curwp] += G_WeaponLogKills[i][j];
00666 }
00667 }
00668
00669 if ( g_entities[i].client )
00670 {
00671 nameptr = g_entities[i].client->pers.netname;
00672 }
00673 else
00674 {
00675 nameptr = unknownname;
00676 }
00677 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00678
00679 for (j=0;j<WP_NUM_WEAPONS;j++)
00680 {
00681 Com_sprintf(string, sizeof(string), "\t%d", percharacter[j]);
00682 trap_FS_Write(string, strlen(string), weaponfile);
00683 }
00684
00685 Com_sprintf(string, sizeof(string), "\n");
00686 trap_FS_Write(string, strlen(string), weaponfile);
00687 }
00688 }
00689
00690
00691 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00692 trap_FS_Write(string, strlen(string), weaponfile);
00693
00694 for (j=0;j<WP_NUM_WEAPONS;j++)
00695 {
00696 Com_sprintf(string, sizeof(string), "\t%d", totalkills[j]);
00697 trap_FS_Write(string, strlen(string), weaponfile);
00698 }
00699
00700 Com_sprintf(string, sizeof(string), "\n\n\n");
00701 trap_FS_Write(string, strlen(string), weaponfile);
00702
00703
00704
00705
00706 Com_sprintf(string, sizeof(string), "Typed Damage per Player:\n\n");
00707 trap_FS_Write( string, strlen( string ), weaponfile);
00708
00709 Com_sprintf(string, sizeof(string), "Player");
00710 trap_FS_Write(string, strlen(string), weaponfile);
00711
00712 for (j=0; j<MOD_MAX; j++)
00713 {
00714 Com_sprintf(string, sizeof(string), "\t%s", modNames[j]);
00715 trap_FS_Write(string, strlen(string), weaponfile);
00716 }
00717 Com_sprintf(string, sizeof(string), "\n");
00718 trap_FS_Write(string, strlen(string), weaponfile);
00719
00720
00721 for (i=0; i<MAX_CLIENTS; i++)
00722 {
00723 if (G_WeaponLogClientTouch[i])
00724 {
00725 if ( g_entities[i].client )
00726 {
00727 nameptr = g_entities[i].client->pers.netname;
00728 }
00729 else
00730 {
00731 nameptr = unknownname;
00732 }
00733 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00734
00735 for (j=0;j<MOD_MAX;j++)
00736 {
00737 Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogDamage[i][j]);
00738 trap_FS_Write(string, strlen(string), weaponfile);
00739 }
00740
00741 Com_sprintf(string, sizeof(string), "\n");
00742 trap_FS_Write(string, strlen(string), weaponfile);
00743 }
00744 }
00745
00746
00747 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00748 trap_FS_Write(string, strlen(string), weaponfile);
00749
00750 for (j=0;j<MOD_MAX;j++)
00751 {
00752 Com_sprintf(string, sizeof(string), "\t%d", totaldamageMOD[j]);
00753 trap_FS_Write(string, strlen(string), weaponfile);
00754 }
00755
00756 Com_sprintf(string, sizeof(string), "\n\n\n");
00757 trap_FS_Write(string, strlen(string), weaponfile);
00758
00759
00760
00761
00762 Com_sprintf(string, sizeof(string), "Damage-Typed Kills per Player:\n\n");
00763 trap_FS_Write( string, strlen( string ), weaponfile);
00764
00765 Com_sprintf(string, sizeof(string), "Player");
00766 trap_FS_Write(string, strlen(string), weaponfile);
00767
00768 for (j=0; j<MOD_MAX; j++)
00769 {
00770 Com_sprintf(string, sizeof(string), "\t%s", modNames[j]);
00771 trap_FS_Write(string, strlen(string), weaponfile);
00772 }
00773 Com_sprintf(string, sizeof(string), "\n");
00774 trap_FS_Write(string, strlen(string), weaponfile);
00775
00776
00777 for (i=0; i<MAX_CLIENTS; i++)
00778 {
00779 if (G_WeaponLogClientTouch[i])
00780 {
00781 if ( g_entities[i].client )
00782 {
00783 nameptr = g_entities[i].client->pers.netname;
00784 }
00785 else
00786 {
00787 nameptr = unknownname;
00788 }
00789 trap_FS_Write(nameptr, strlen(nameptr), weaponfile);
00790
00791 for (j=0;j<MOD_MAX;j++)
00792 {
00793 Com_sprintf(string, sizeof(string), "\t%d", G_WeaponLogKills[i][j]);
00794 trap_FS_Write(string, strlen(string), weaponfile);
00795 }
00796
00797 Com_sprintf(string, sizeof(string), "\n");
00798 trap_FS_Write(string, strlen(string), weaponfile);
00799 }
00800 }
00801
00802
00803 Com_sprintf(string, sizeof(string), "\n***TOTAL:");
00804 trap_FS_Write(string, strlen(string), weaponfile);
00805
00806 for (j=0;j<MOD_MAX;j++)
00807 {
00808 Com_sprintf(string, sizeof(string), "\t%d", totalkillsMOD[j]);
00809 trap_FS_Write(string, strlen(string), weaponfile);
00810 }
00811
00812 Com_sprintf(string, sizeof(string), "\n\n\n");
00813 trap_FS_Write(string, strlen(string), weaponfile);
00814
00815
00816 trap_FS_FCloseFile(weaponfile);
00817
00818
00819 #endif //LOGGING_WEAPONS
00820 }
00821
00822
00823 qboolean CalculateEfficiency(gentity_t *ent, int *efficiency)
00824 {
00825 #ifdef LOGGING_WEAPONS
00826 float fAccuracyRatio = 0, fBestRatio = 0;
00827 int i = 0, nShotsFired = 0, nShotsHit = 0, nBestPlayer = -1, tempEff = 0;
00828 gentity_t *player = NULL;
00829
00830
00831 for (i = 0; i < g_maxclients.integer; i++)
00832 {
00833 player = g_entities + i;
00834 if (!player->inuse)
00835 continue;
00836 nShotsFired = player->client->accuracy_shots;
00837 nShotsHit = player->client->accuracy_hits;
00838 fAccuracyRatio = ( ((float)nShotsHit)/((float)nShotsFired) );
00839 if (fAccuracyRatio > fBestRatio)
00840 {
00841 fBestRatio = fAccuracyRatio;
00842 nBestPlayer = i;
00843 }
00844 }
00845 if (-1 == nBestPlayer)
00846 {
00847
00848 return qfalse;
00849 }
00850 if (nBestPlayer == ent->s.number)
00851 {
00852 tempEff = (int)(100*fBestRatio);
00853 if (tempEff > 50)
00854 {
00855 *efficiency = tempEff;
00856 return qtrue;
00857 }
00858 return qfalse;
00859 }
00860 #endif // LOGGING_WEAPONS
00861 return qfalse;
00862 }
00863
00864
00865 qboolean CalculateSharpshooter(gentity_t *ent, int *frags)
00866 {
00867 #ifdef LOGGING_WEAPONS
00868 int i = 0, nBestPlayer = -1, nKills = 0, nMostKills = 0,
00869 playTime = (level.time - ent->client->pers.enterTime)/60000;
00870 gentity_t *player = NULL;
00871
00872
00873 if ( ((float)(G_WeaponLogKills[ent-g_entities][MOD_DISRUPTOR_SNIPER]))/((float)(playTime)) < 1.0 )
00874 {
00875 return qfalse;
00876 }
00877
00878 for (i = 0; i < g_maxclients.integer; i++)
00879 {
00880 nKills = 0;
00881 player = g_entities + i;
00882 if (!player->inuse)
00883 continue;
00884 nKills = G_WeaponLogKills[i][MOD_DISRUPTOR_SNIPER];
00885 if (nKills > nMostKills)
00886 {
00887 nMostKills = nKills;
00888 nBestPlayer = i;
00889 }
00890 }
00891 if (-1 == nBestPlayer)
00892 {
00893 return qfalse;
00894 }
00895 if (nBestPlayer == ent->s.number)
00896 {
00897 *frags = nMostKills;
00898 return qtrue;
00899 }
00900 #endif // LOGGING_WEAPONS
00901 return qfalse;
00902 }
00903
00904
00905 qboolean CalculateUntouchable(gentity_t *ent)
00906 {
00907 #ifdef LOGGING_WEAPONS
00908 int playTime;
00909 playTime = (level.time - ent->client->pers.enterTime)/60000;
00910
00911 if ( g_gametype.integer == GT_JEDIMASTER && ent->client->ps.isJediMaster )
00912 {
00913 return qfalse;
00914 }
00915
00916 if ( ((float)ent->client->ps.persistant[PERS_SCORE])/((float)(playTime)) < 2.0 || playTime==0)
00917 return qfalse;
00918
00919
00920
00921
00922 if (ent->client->ps.persistant[PERS_KILLED]==0)
00923 return qtrue;
00924
00925 #endif // LOGGING_WEAPONS
00926 return qfalse;
00927 }
00928
00929
00930 qboolean CalculateLogistics(gentity_t *ent, int *stuffUsed)
00931 {
00932 #ifdef LOGGING_WEAPONS
00933 int i = 0, j = 0, nBestPlayer = -1, nStuffUsed = 0, nMostStuffUsed = 0,
00934 nDifferent = 0, nMostDifferent = 0;
00935 gentity_t *player = NULL;
00936
00937 for (i = 0; i < g_maxclients.integer; i++)
00938 {
00939 nStuffUsed = 0;
00940 nDifferent = 0;
00941 player = g_entities + i;
00942 if (!player->inuse)
00943 continue;
00944 for (j = HI_NONE+1; j < HI_NUM_HOLDABLE; j++)
00945 {
00946 if (G_WeaponLogPowerups[i][j])
00947 {
00948 nDifferent++;
00949 }
00950 nStuffUsed += G_WeaponLogPowerups[i][j];
00951 }
00952 for (j = PW_NONE+1; j < PW_NUM_POWERUPS; j++)
00953 {
00954 if (G_WeaponLogItems[i][j])
00955 {
00956 nDifferent++;
00957 }
00958 nStuffUsed += G_WeaponLogItems[i][j];
00959 }
00960 if ( (nDifferent >= 4) && (nDifferent >= nMostDifferent) )
00961 {
00962 if (nStuffUsed > nMostStuffUsed)
00963 {
00964 nMostDifferent = nDifferent;
00965 nMostStuffUsed = nStuffUsed;
00966 nBestPlayer = i;
00967 }
00968 }
00969 }
00970 if (-1 == nBestPlayer)
00971 {
00972 return qfalse;
00973 }
00974 if (nBestPlayer == ent->s.number)
00975 {
00976 *stuffUsed = nMostDifferent;
00977 return qtrue;
00978 }
00979 #endif // LOGGING_WEAPONS
00980 return qfalse;
00981 }
00982
00983
00984
00985
00986
00987 qboolean CalculateTactician(gentity_t *ent, int *kills)
00988 {
00989 #ifdef LOGGING_WEAPONS
00990 int i = 0, nBestPlayer = -1, nKills = 0, nMostKills = 0;
00991 int person = 0, weapon = 0;
00992 gentity_t *player = NULL;
00993 int wasPickedUpBySomeone[WP_NUM_WEAPONS];
00994 int killsWithWeapon[WP_NUM_WEAPONS];
00995 int playTime = (level.time - ent->client->pers.enterTime)/60000;
00996
00997 if ( HasSetSaberOnly() )
00998 {
00999 return qfalse;
01000 }
01001 if ( g_gametype.integer == GT_JEDIMASTER && ent->client->ps.isJediMaster )
01002 {
01003 return qfalse;
01004 }
01005
01006 if (playTime<0.3)
01007 return qfalse;
01008
01009 if ( ((float)ent->client->ps.persistant[PERS_SCORE])/((float)(playTime)) < 2.0 )
01010 return qfalse;
01011
01012
01013
01014
01015
01016
01017 for (weapon = 0; weapon<WP_NUM_WEAPONS; weapon++)
01018 wasPickedUpBySomeone[weapon] = 0;
01019
01020 for (person=0; person<g_maxclients.integer; person++)
01021 {
01022 for (weapon = 0; weapon<WP_NUM_WEAPONS; weapon++)
01023 {
01024 if (G_WeaponLogPickups[person][weapon]>0)
01025 wasPickedUpBySomeone[weapon]++;
01026 }
01027 }
01028
01029
01030
01031
01032
01033
01034 for (person=0; person<g_maxclients.integer; person++)
01035 {
01036 player = g_entities + person;
01037 if (!player->inuse) continue;
01038
01039 nKills = 0;
01040 for (weapon=0; weapon<WP_NUM_WEAPONS; weapon++)
01041 killsWithWeapon[weapon] = 0;
01042
01043 for (i=0; i<MOD_MAX; i++)
01044 {
01045 weapon = weaponFromMOD[i];
01046 killsWithWeapon[weapon] += G_WeaponLogKills[person][i];
01047 }
01048
01049 weapon=WP_STUN_BATON;
01050
01051 while( weapon<WP_NUM_WEAPONS && (!wasPickedUpBySomeone[weapon] || killsWithWeapon[weapon]>0) )
01052 {
01053 weapon++;
01054 nKills+=killsWithWeapon[weapon];
01055 }
01056
01057
01058
01059
01060
01061
01062
01063 if (weapon>=WP_NUM_WEAPONS && nKills>nMostKills)
01064 {
01065
01066 nMostKills = nKills;
01067 nBestPlayer = person;
01068 }
01069 }
01070
01071
01072
01073 if (nBestPlayer == ent->s.number)
01074 {
01075 *kills = nMostKills;
01076 return qtrue;
01077 }
01078 #endif // LOGGING_WEAPONS
01079 return qfalse;
01080 }
01081
01082
01083
01084
01085
01086 qboolean CalculateDemolitionist(gentity_t *ent, int *kills)
01087 {
01088 #ifdef LOGGING_WEAPONS
01089 int i = 0, nBestPlayer = -1, nKills = 0, nMostKills = 0,
01090 playTime = (level.time - ent->client->pers.enterTime)/60000;
01091 gentity_t *player = NULL;
01092
01093 for (i = 0; i < g_maxclients.integer; i++)
01094 {
01095 nKills = 0;
01096 player = g_entities + i;
01097 if (!player->inuse)
01098 continue;
01099
01100 nKills = G_WeaponLogKills[i][MOD_THERMAL];
01101 nKills += G_WeaponLogKills[i][MOD_THERMAL_SPLASH];
01102 nKills += G_WeaponLogKills[i][MOD_ROCKET];
01103 nKills += G_WeaponLogKills[i][MOD_ROCKET_SPLASH];
01104 nKills += G_WeaponLogKills[i][MOD_ROCKET_HOMING];
01105 nKills += G_WeaponLogKills[i][MOD_ROCKET_HOMING_SPLASH];
01106 nKills += G_WeaponLogKills[i][MOD_TRIP_MINE_SPLASH];
01107 nKills += G_WeaponLogKills[i][MOD_TIMED_MINE_SPLASH];
01108 nKills += G_WeaponLogKills[i][MOD_DET_PACK_SPLASH];
01109
01110
01111 if ( ((float)nKills)/((float)(playTime)) < 2.0 )
01112 {
01113 continue;
01114 }
01115
01116 if (nKills > nMostKills)
01117 {
01118 nMostKills = nKills;
01119 nBestPlayer = i;
01120 }
01121 }
01122 if (-1 == nBestPlayer)
01123 {
01124 return qfalse;
01125 }
01126 if (nBestPlayer == ent->s.number)
01127 {
01128 *kills = nMostKills;
01129 return qtrue;
01130 }
01131 #endif // LOGGING_WEAPONS
01132 return qfalse;
01133 }
01134
01135 int CalculateStreak(gentity_t *ent)
01136 {
01137 #if 0
01138 if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_CHAMPION)
01139 {
01140 return STREAK_CHAMPION;
01141 }
01142 if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_MASTER)
01143 {
01144 return STREAK_MASTER;
01145 }
01146 if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_EXPERT)
01147 {
01148 return STREAK_EXPERT;
01149 }
01150 if (ent->client->ps.persistant[PERS_STREAK_COUNT] >= STREAK_ACE)
01151 {
01152 return STREAK_ACE;
01153 }
01154 #endif
01155
01156 return 0;
01157 }
01158
01159 qboolean CalculateTeamMVP(gentity_t *ent)
01160 {
01161 int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0,
01162 team = ent->client->ps.persistant[PERS_TEAM];
01163 gentity_t *player = NULL;
01164
01165 for (i = 0; i < g_maxclients.integer; i++)
01166 {
01167 nScore = 0;
01168 player = g_entities + i;
01169 if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team))
01170 continue;
01171 nScore = player->client->ps.persistant[PERS_SCORE];
01172 if (nScore > nHighestScore)
01173 {
01174 nHighestScore = nScore;
01175 nBestPlayer = i;
01176 }
01177 }
01178 if (-1 == nBestPlayer)
01179 {
01180 return qfalse;
01181 }
01182 if (nBestPlayer == ent->s.number)
01183 {
01184 return qtrue;
01185 }
01186 return qfalse;
01187 }
01188
01189 qboolean CalculateTeamMVPByRank(gentity_t *ent)
01190 {
01191 int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0,
01192 team = ent->client->ps.persistant[PERS_RANK]+1;
01193 qboolean bTied = (team == 3);
01194 gentity_t *player = NULL;
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210 for (i = 0; i < g_maxclients.integer; i++)
01211 {
01212 nScore = 0;
01213 player = g_entities + i;
01214 if (!player->inuse)
01215 continue;
01216 if (!bTied)
01217 {
01218 if (player->client->ps.persistant[PERS_TEAM] != team)
01219 {
01220 continue;
01221 }
01222 }
01223 nScore = player->client->ps.persistant[PERS_SCORE];
01224 if (nScore > nHighestScore)
01225 {
01226 nHighestScore = nScore;
01227 nBestPlayer = i;
01228 }
01229 }
01230 if (-1 == nBestPlayer)
01231 {
01232 return qfalse;
01233 }
01234 if (nBestPlayer == ent->s.number)
01235 {
01236 return qtrue;
01237 }
01238 return qfalse;
01239 }
01240
01241 qboolean CalculateTeamDefender(gentity_t *ent)
01242 {
01243 int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0,
01244 team = ent->client->ps.persistant[PERS_TEAM];
01245 gentity_t *player = NULL;
01246
01247
01248
01249
01250
01251
01252
01253 for (i = 0; i < g_maxclients.integer; i++)
01254 {
01255 nScore = 0;
01256 player = g_entities + i;
01257 if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team))
01258 continue;
01259 nScore = player->client->pers.teamState.basedefense;
01260 if (nScore > nHighestScore)
01261 {
01262 nHighestScore = nScore;
01263 nBestPlayer = i;
01264 }
01265 }
01266 if (-1 == nBestPlayer)
01267 {
01268 return qfalse;
01269 }
01270 if (nBestPlayer == ent->s.number)
01271 {
01272 return qtrue;
01273 }
01274 return qfalse;
01275 }
01276
01277 qboolean CalculateTeamWarrior(gentity_t *ent)
01278 {
01279 int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0,
01280 team = ent->client->ps.persistant[PERS_TEAM];
01281 gentity_t *player = NULL;
01282
01283
01284
01285
01286
01287
01288
01289 for (i = 0; i < g_maxclients.integer; i++)
01290 {
01291 nScore = 0;
01292 player = g_entities + i;
01293 if (!player->inuse || (player->client->ps.persistant[PERS_TEAM] != team))
01294 continue;
01295 nScore = player->client->ps.persistant[PERS_SCORE];
01296 if (nScore > nHighestScore)
01297 {
01298 nHighestScore = nScore;
01299 nBestPlayer = i;
01300 }
01301 }
01302 if (-1 == nBestPlayer)
01303 {
01304 return qfalse;
01305 }
01306 if (nBestPlayer == ent->s.number)
01307 {
01308 return qtrue;
01309 }
01310 return qfalse;
01311 }
01312
01313 qboolean CalculateTeamCarrier(gentity_t *ent)
01314 {
01315 int i = 0, nBestPlayer = -1, nScore = 0, nHighestScore = 0,
01316 team = ent->client->ps.persistant[PERS_TEAM];
01317 gentity_t *player = NULL;
01318
01319
01320
01321
01322
01323
01324
01325 for (i = 0; i <