// DRESK - Client Statistics / Scoring // Provides definitions and default values for client scoring / statistics. #define CLIENTSCORE_NUMKILLS 0 #define CLIENTSCORE_NUMDEATHS 1 #define CLIENTSCORE_NUMITEMSPICKEDUP 2 #define CLIENTSCORE_NUMSECRETSFOUND 3 #define CLIENTSCORE_TOTALDAMAGEDEALT 4 #define CLIENTSCORE_TOTALDAMAGERECEIVED 5 #define CLIENTSCORE_NUMSTATS 6 #define CLIENTSCORE_COLUMN_LENGTH 12 // Specify if Array Storage Should be Used #define CLIENTSCORE_USEARRAYSTORAGE // Prepare Scoring Array Here for Automated Header Printer string strClientScoreHeaders[CLIENTSCORE_NUMSTATS]; string strClientScoreArray[CLIENTSCORE_NUMSTATS]; // Support Additional Client Scores // NOTE: Not using Client Score Array System until FTEQCC supports field arrays (not just global arrays) // UPDATE: Thanks to div0 for pointing out FTEQCC does support field arrays. // UPDATE 2: FTEQCC is crashing when using arrays, so making it a preprocessor definition // UPDATE 3: FTEQCC is crashing when using #ifdefs, so NOW I am making it variable based // UPDATE 4: I officially have no idea what the fuck is going on. #ifdef CLIENTSCORE_USEARRAYSTORAGE .float nClientScores[CLIENTSCORE_NUMSTATS]; // #else .float nClientScore_NumKills; .float nClientScore_NumDeaths; .float nClientScore_NumItemsPickedUp; .float nClientScore_NumSecretsFound; .float nClientScore_TotalDamageDealt; .float nClientScore_TotalDamageReceived; #endif float GetClientStatsScore(entity enClient, float nScoreType) { // Return Clients Stats Score // NOTE: The primary usage of this function is to allow for easy IFDEF capability for switching between // the array storage method or the multiple variable storage method. local float nReturn; #ifdef CLIENTSCORE_USEARRAYSTORAGE nReturn = enClient.(nClientScores[nScoreType]); #else if(nScoreType == CLIENTSCORE_NUMKILLS) nReturn = enClient.nClientScore_NumKills; else if(nScoreType == CLIENTSCORE_NUMDEATHS) nReturn = enClient.nClientScore_NumDeaths; else if(nScoreType == CLIENTSCORE_NUMITEMSPICKEDUP) nReturn = enClient.nClientScore_NumItemsPickedUp; else if(nScoreType == CLIENTSCORE_NUMSECRETSFOUND) nReturn = enClient.nClientScore_NumSecretsFound; else if(nScoreType == CLIENTSCORE_TOTALDAMAGEDEALT) nReturn = enClient.nClientScore_TotalDamageDealt; else if(nScoreType == CLIENTSCORE_TOTALDAMAGERECEIVED) nReturn = enClient.nClientScore_TotalDamageReceived; #endif // Return Value return nReturn; } void UpdateClientStatsScore(entity enClient, float nScoreType, float fMod) { // Update Clients Stats Score // NOTE: The primary usage of this function is to allow for easy IFDEF capability for switching between // the array storage method or the multiple variable storage method. #ifdef CLIENTSCORE_USEARRAYSTORAGE enClient.(nClientScores[nScoreType]) = enClient.(nClientScores[nScoreType]) + fMod; #else if(nScoreType == CLIENTSCORE_NUMKILLS) enClient.nClientScore_NumKills = enClient.nClientScore_NumKills + fMod; else if(nScoreType == CLIENTSCORE_NUMDEATHS) enClient.nClientScore_NumDeaths = enClient.nClientScore_NumDeaths + fMod; else if(nScoreType == CLIENTSCORE_NUMITEMSPICKEDUP) enClient.nClientScore_NumItemsPickedUp = enClient.nClientScore_NumItemsPickedUp + fMod; else if(nScoreType == CLIENTSCORE_NUMSECRETSFOUND) enClient.nClientScore_NumSecretsFound = enClient.nClientScore_NumSecretsFound + fMod; else if(nScoreType == CLIENTSCORE_TOTALDAMAGEDEALT) enClient.nClientScore_TotalDamageDealt = enClient.nClientScore_TotalDamageDealt + fMod; else if(nScoreType == CLIENTSCORE_TOTALDAMAGERECEIVED) enClient.nClientScore_TotalDamageReceived = enClient.nClientScore_TotalDamageReceived + fMod; #endif } void PrepareClientScoringHeaderArray() { // Prepare Client Scoring Header Array local float nCnt; nCnt = 0; strClientScoreHeaders[nCnt] = "\bPlayer"; nCnt = nCnt + 1; strClientScoreHeaders[nCnt] = "\bKills"; nCnt = nCnt + 1; strClientScoreHeaders[nCnt] = "\bDeaths"; nCnt = nCnt + 1; strClientScoreHeaders[nCnt] = "\bItems"; nCnt = nCnt + 1; strClientScoreHeaders[nCnt] = "\bSecrets"; nCnt = nCnt + 1; strClientScoreHeaders[nCnt] = "\bDamage Dealt / Taken"; nCnt = nCnt + 1; /* strClientScoreHeaders[nCnt] = "Damage Taken"; nCnt = nCnt + 1; */ } void PrepareClientScoringArray(entity enPlayer) { // Prepare Client Scoring Array local float nCnt; nCnt = 0; // Player Name strClientScoreArray[nCnt] = enPlayer.netname; nCnt = nCnt + 1; // Number of Kills strClientScoreArray[nCnt] = strzone(ftos( GetClientStatsScore(enPlayer, CLIENTSCORE_NUMKILLS) )); nCnt = nCnt + 1; // Number of Deaths strClientScoreArray[nCnt] = strzone(ftos( GetClientStatsScore(enPlayer, CLIENTSCORE_NUMDEATHS) )); nCnt = nCnt + 1; // Number of Items Picked Up strClientScoreArray[nCnt] = strzone(ftos( GetClientStatsScore(enPlayer, CLIENTSCORE_NUMITEMSPICKEDUP) )); nCnt = nCnt + 1; // Number of Secrets Found strClientScoreArray[nCnt] = strzone(ftos( GetClientStatsScore(enPlayer, CLIENTSCORE_NUMSECRETSFOUND) )); nCnt = nCnt + 1; // Total Damage Dealt / Taken strClientScoreArray[nCnt] = strzone(ftos( GetClientStatsScore(enPlayer, CLIENTSCORE_NUMKILLS) )); nCnt = nCnt + 1; } void PurgeClientScoringArray() { // Purge Client Scoring Array local float nCnt; for(nCnt = 1; nCnt < CLIENTSCORE_NUMSTATS; nCnt++) strunzone( strClientScoreArray[nCnt] ); } string AppendClientScoringRow(string strMessage, entity enPlayer) { // Append Client Scoring Row local float nCnt; local float nSpacingCnt; local float nSpacingNeeded; // Generate Client Scoring Array PrepareClientScoringArray(enPlayer); // Append Return strMessage = strcat(strMessage, "\n"); for(nCnt = 0; nCnt < CLIENTSCORE_NUMSTATS; nCnt++) { // Traverse Scoring Array // Calculate Spacing Needed nSpacingNeeded = CLIENTSCORE_COLUMN_LENGTH - strlennocol( strClientScoreArray[nCnt]); // Append Spacing for(nSpacingCnt = 0; nSpacingCnt < nSpacingNeeded; nSpacingCnt++) strMessage = strcat(strMessage, " "); // Append Header strMessage = strcat(strMessage, strClientScoreArray[nCnt]); } // Purge Client Scoring Array PurgeClientScoringArray(); // Return Appended String return strMessage; } string AppendClientScoringRowHeaders(string strMessage) { // Append Client Scoring Row Headers // Append Return strMessage = strcat(strMessage, "\n"); // Print Headers local float nCnt; local float nSpacingCnt; local float nSpacingNeeded; for(nCnt = 0; nCnt < CLIENTSCORE_NUMSTATS; nCnt++) { // Traverse Scoring Array // Calculate Spacing Needed nSpacingNeeded = CLIENTSCORE_COLUMN_LENGTH - strlen( strClientScoreHeaders[nCnt]); // Append Header strMessage = strcat(strMessage, strClientScoreHeaders[nCnt]); // Append Spacing for(nSpacingCnt = 0; nSpacingCnt < nSpacingNeeded; nSpacingCnt++) strMessage = strcat(strMessage, " "); } // Return New String return strMessage; } void PrintClientScoring(entity enPlayer, float bIntermission) { // Print Client Scoring local string strMessage; local entity enPlayerFind; PrepareClientScoringHeaderArray(); // Print Title strMessage = "\bKLESHIK CLIENT STATISTICS / SCORING\b\n\n"; // Print Row Headers strMessage = AppendClientScoringRowHeaders(strMessage); // Print Client Rows // Acquire First Player enPlayerFind = find(world, classname, "player"); while(enPlayerFind != world) { // Valid Player // Append Client Scoring Raw strMessage = AppendClientScoringRow(strMessage, enPlayerFind); // Acquire Next Player enPlayerFind = find(enPlayerFind, classname, "player"); } // Display Scoring to Client centerprint(enPlayer, strMessage); }