Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
4.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #include "MatchResults.h"
  9. void CMatchResults::init()
  10. {
  11. memset(teams,0,sizeof(team)*MAX_TEAMS);
  12. memset(loserString,0,STRLEN);
  13. memset(winnerString,0,STRLEN);
  14. valid=false;
  15. draw=false;
  16. numTeams=0;
  17. }
  18. void CMatchResults::generate()
  19. {
  20. CEventListIterator it=g_pMatchInfo->eventList()->end();
  21. --it;
  22. for (it=g_pMatchInfo->eventList()->begin();it!=g_pMatchInfo->eventList()->end();++it)
  23. {
  24. if ((*it)->getType()==CLogEvent::MATCH_RESULTS_MARKER)
  25. valid=true;
  26. else if ((*it)->getType()==CLogEvent::MATCH_DRAW)
  27. {
  28. draw=true;
  29. }
  30. else if ((*it)->getType()==CLogEvent::MATCH_VICTOR)
  31. {
  32. //winning teams are recited first, then losing teams. so start in "winning" mode
  33. bool fWinMode=true;
  34. char eventText[200];
  35. strcpy(eventText,(*it)->getFullMessage());
  36. char seps[] = " \n\t";
  37. char *token;
  38. token = strtok( eventText, seps );
  39. while( token != NULL )
  40. {
  41. if (stricmp(token,"defeated")==0)
  42. fWinMode=false;
  43. else if (token[0]=='\"')
  44. {
  45. //found a team name
  46. //depending on win/lose mode, assign that team appropriately
  47. token++; //advance past the first quote
  48. char* quote2=strchr(token,'\"');
  49. *quote2='\0'; //null out the second quote;
  50. //get team ID
  51. int tID=g_pMatchInfo->teamID(token);
  52. teams[tID].fWinner=fWinMode;
  53. }
  54. //Get next token
  55. token = strtok( NULL, seps );
  56. }
  57. }
  58. else if ((*it)->getType()==CLogEvent::MATCH_TEAM_RESULTS)
  59. {
  60. int team=g_pMatchInfo->teamID((*it)->getArgument(0)->getStringValue());
  61. teams[team].valid=true;
  62. teams[team].numplayers=(*it)->getArgument(1)->getFloatValue();
  63. teams[team].frags=(*it)->getArgument(2)->getFloatValue();
  64. teams[team].unacc_frags=(*it)->getArgument(3)->getFloatValue();
  65. teams[team].score=(*it)->getArgument(4)->getFloatValue();
  66. for (int i=0;i<MAX_TEAMS;i++)
  67. {
  68. teams[team].allies[i]= (i==team); //initially set team to be allied with itself.
  69. }
  70. //get allies
  71. i=5;
  72. CLogEventArgument const * pArg=(*it)->getArgument(i++);
  73. while(pArg)
  74. {
  75. int ally=pArg->getFloatValue()-1;
  76. teams[team].allies[ally]=true;
  77. teams[ally].allies[team]=true; //one sided alliances don't exist.
  78. pArg=(*it)->getArgument(i++);
  79. }
  80. }
  81. }
  82. }
  83. char* CMatchResults::getWinnerTeamsString()
  84. {
  85. bool firstWinner=true;
  86. for (int i=0;i<MAX_TEAMS;i++)
  87. {
  88. if (teams[i].valid && teams[i].fWinner)
  89. {
  90. if (!firstWinner)
  91. strcat(winnerString," and ");
  92. strcat(winnerString,g_pMatchInfo->teamName(i).c_str());
  93. firstWinner=false;
  94. }
  95. }
  96. return winnerString;
  97. }
  98. int CMatchResults::getWinnerTeamScore()
  99. {
  100. if (draw)
  101. return teams[0].score;
  102. for (int i=0;i<MAX_TEAMS;i++)
  103. if (teams[i].valid && teams[i].fWinner)
  104. return teams[i].score;
  105. return 0;
  106. }
  107. void CMatchResults::calcRealWinners()
  108. {
  109. //first find the highest score.
  110. int maxScoreTeam=0;
  111. for (int i=0;i<MAX_TEAMS;i++)
  112. {
  113. teams[i].fWinner=false;
  114. if (teams[i].score > teams[maxScoreTeam].score)
  115. maxScoreTeam=i;
  116. }
  117. //mark that team as a winner, then mark all their allies as winners
  118. teams[maxScoreTeam].fWinner=true;
  119. for (int j=0;j<MAX_TEAMS;j++)
  120. {
  121. if (teams[maxScoreTeam].allies[j])
  122. teams[j].fWinner=true;
  123. }
  124. }
  125. char* CMatchResults::getLoserTeamsString()
  126. {
  127. bool firstLoser=true;
  128. for (int i=0;i<MAX_TEAMS;i++)
  129. {
  130. if (teams[i].valid && !teams[i].fWinner)
  131. {
  132. if (!firstLoser)
  133. strcat(loserString," and ");
  134. strcat(loserString,g_pMatchInfo->teamName(i).c_str());
  135. firstLoser=false;
  136. }
  137. }
  138. return loserString;
  139. }
  140. int CMatchResults::getLoserTeamScore()
  141. {
  142. if (draw)
  143. return teams[0].score;
  144. for (int i=0;i<MAX_TEAMS;i++)
  145. if (teams[i].valid && !teams[i].fWinner)
  146. return teams[i].score;
  147. return 0;
  148. }
  149. bool CMatchResults::Outnumbered(int WinnerOrLoser)
  150. {
  151. int losers=0;
  152. int winners=0;
  153. for (int i=0;i<MAX_TEAMS;i++)
  154. {
  155. if (teams[i].fWinner)
  156. winners+=teams[i].numplayers;
  157. else
  158. losers+=teams[i].numplayers;
  159. }
  160. if (WinnerOrLoser == WINNER)
  161. return losers > winners;
  162. else
  163. return losers < winners;
  164. }
  165. int CMatchResults::numWinningTeams()
  166. {
  167. int num=0;
  168. for (int i=0;i<MAX_TEAMS;i++)
  169. {
  170. if (teams[i].fWinner) num++;
  171. }
  172. return num;
  173. }
  174. void CMatchResults::writeHTML(CHTMLFile& html)
  175. {
  176. calcRealWinners(); //deal with logging bug in DLL
  177. html.write("<div class=headline>\n");
  178. if (!valid)
  179. html.write("No winner has been determined.");
  180. else if (!draw)
  181. {
  182. bool fOutnumbered=false;
  183. bool winPlural=numWinningTeams()==1;
  184. html.write("%s %s! They scored %li points to %s's %li\n",getWinnerTeamsString(),winPlural?"wins":"win",getWinnerTeamScore(),getLoserTeamsString(),getLoserTeamScore());
  185. }
  186. else
  187. html.write("The match ends in a draw! <br> All teams scored %li \n",getWinnerTeamScore());
  188. html.write("</div>");
  189. }