daily pastebin goal
1%
SHARE
TWEET

Untitled

a guest Mar 23rd, 2019 117 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <amxmodx>
  2. #include <amxmisc>
  3. #include <csx>
  4.  
  5. new const g_szTopColors[ ][ ] = {
  6.     "#FF0000",
  7.     "#00FFFF",
  8.     "#00FF00"
  9. };
  10.  
  11. //#define STATSX_DEBUG
  12.  
  13. // HUD statistics duration in seconds (minimum 1.0 seconds).
  14. #define HUD_DURATION_CVAR   "amx_statsx_duration"
  15. #define HUD_DURATION        "12.0"
  16.  
  17. // HUD statistics stop relative freeze end in seconds.
  18. // To stop before freeze end use a negative value.
  19. #define HUD_FREEZE_LIMIT_CVAR   "amx_statsx_freeze"
  20. #define HUD_FREEZE_LIMIT        "-2.0"
  21.  
  22. // HUD statistics minimum duration, in seconds, to trigger the display logic.
  23. #define HUD_MIN_DURATION    0.2
  24.  
  25. // Config plugin constants.
  26. #define MODE_HUD_DELAY      0   // Make a 0.01 sec delay on HUD reset process.
  27.  
  28. // You can also manualy enable or disable these options by setting them to 1
  29. // For example:
  30. // public ShowAttackers = 1
  31. // However amx_statscfg command is recommended
  32.  
  33. public KillerChat           = 0 // displays killer hp&ap to victim console
  34.                                 // and screen
  35.  
  36. public ShowAttackers        = 0 // shows attackers
  37. public ShowVictims          = 0 // shows victims
  38. public ShowKiller           = 0 // shows killer
  39. public ShowTeamScore        = 0 // shows team score at round end
  40. public ShowTotalStats       = 0 // shows round total stats
  41. public ShowBestScore        = 0 // shows rounds best scored player
  42. public ShowMostDisruptive   = 0 // shows rounds most disruptive player
  43.  
  44. public EndPlayer            = 0 // displays player stats at the end of map
  45. public EndTop15             = 0 // displays top15 at the end of map
  46.  
  47. public SayHP                = 0 // displays information about user killer
  48. public SayStatsMe           = 0 // displays user's stats and rank
  49. public SayRankStats         = 0 // displays user's rank stats
  50. public SayMe                = 0 // displays user's stats
  51. public SayRank              = 0 // displays user's rank
  52. public SayReport            = 0 // report user's weapon status to team
  53. public SayScore             = 0 // displays team's map score
  54. public SayTop15             = 0 // displays first 15 players
  55. public SayStatsAll          = 0 // displays all players stats and rank
  56.  
  57. public ShowStats            = 1 // set client HUD-stats switched off by default
  58. public ShowDistHS           = 0 // show distance and HS in attackers and
  59.                                 //  victims HUD lists
  60. public ShowFullStats        = 0 // show full HUD stats (more than 78 chars)
  61.  
  62. public SpecRankInfo         = 0 // displays rank info when spectating
  63.  
  64. // Standard Contstants.
  65. #define MAX_TEAMS               2
  66. #define MAX_PLAYERS             32 + 1
  67.  
  68. #define MAX_NAME_LENGTH         31
  69. #define MAX_WEAPON_LENGTH       31
  70. #define MAX_TEXT_LENGTH         255
  71. #define MAX_BUFFER_LENGTH       2047
  72.  
  73. // User stats parms id
  74. #define STATS_KILLS             0
  75. #define STATS_DEATHS            1
  76. #define STATS_HS                2
  77. #define STATS_TKS               3
  78. #define STATS_SHOTS             4
  79. #define STATS_HITS              5
  80. #define STATS_DAMAGE            6
  81.  
  82. // Global player flags.
  83. new BODY_PART[8][] =
  84. {
  85.     "WHOLEBODY",
  86.     "HEAD",
  87.     "CHEST",
  88.     "STOMACH",
  89.     "LEFTARM",
  90.     "RIGHTARM",
  91.     "LEFTLEG",
  92.     "RIGHTLEG"
  93. }
  94.  
  95. // Killer information, save killer info at the time when player is killed.
  96. #define KILLED_KILLER_ID        0   // Killer userindex/user-ID
  97. #define KILLED_KILLER_HEALTH    1   // Killer's health
  98. #define KILLED_KILLER_ARMOUR    2   // Killer's armour
  99. #define KILLED_TEAM             3   // Killer's team
  100. #define KILLED_KILLER_STATSFIX  4   // Fix to register the last hit/kill
  101.  
  102. new g_izKilled[MAX_PLAYERS][5]
  103.  
  104. // Menu variables and configuration
  105. #define MAX_PPL_MENU_ACTIONS    2   // Number of player menu actions
  106. #define PPL_MENU_OPTIONS        7   // Number of player options per displayed menu
  107.  
  108. new g_iPluginMode                                   = 0
  109.  
  110. new g_izUserMenuPosition[MAX_PLAYERS]               = {0, ...}
  111. new g_izUserMenuAction[MAX_PLAYERS]                 = {0, ...}
  112. new g_izUserMenuPlayers[MAX_PLAYERS][32]
  113.  
  114. new g_izSpecMode[MAX_PLAYERS]                       = {0, ...}
  115.  
  116. new g_izShowStatsFlags[MAX_PLAYERS]                 = {0, ...}
  117. new g_izStatsSwitch[MAX_PLAYERS]                    = {0, ...}
  118. new Float:g_fzShowUserStatsTime[MAX_PLAYERS]        = {0.0, ...}
  119. new Float:g_fShowStatsTime                          = 0.0
  120. new Float:g_fFreezeTime                             = 0.0
  121. new Float:g_fFreezeLimitTime                        = 0.0
  122. new Float:g_fHUDDuration                            = 0.0
  123.  
  124. new g_iRoundEndTriggered                            = 0
  125. new g_iRoundEndProcessed                            = 0
  126.  
  127. new Float:g_fStartGame                              = 0.0
  128. new g_izTeamScore[MAX_TEAMS]                        = {0, ...}
  129. new g_izTeamEventScore[MAX_TEAMS]                   = {0, ...}
  130. new g_izTeamRndStats[MAX_TEAMS][8]
  131. new g_izTeamGameStats[MAX_TEAMS][8]
  132. new g_izUserUserID[MAX_PLAYERS]                     = {0, ...}
  133. new g_izUserAttackerDistance[MAX_PLAYERS]           = {0, ...}
  134. new g_izUserVictimDistance[MAX_PLAYERS][MAX_PLAYERS]
  135. new g_izUserRndName[MAX_PLAYERS][MAX_NAME_LENGTH + 1]
  136. new g_izUserRndStats[MAX_PLAYERS][8]
  137. new g_izUserGameStats[MAX_PLAYERS][8]
  138.  
  139. // Common buffer to improve performance, as Small always zero-initializes all vars
  140. new g_sBuffer[MAX_BUFFER_LENGTH + 1]                = ""
  141. new g_sScore[MAX_TEXT_LENGTH + 1]                   = ""
  142. new g_sAwardAndScore[MAX_BUFFER_LENGTH + 1]         = ""
  143.  
  144. new t_sText[MAX_TEXT_LENGTH + 1]                    = ""
  145. new t_sName[MAX_NAME_LENGTH + 1]                    = ""
  146. new t_sWpn[MAX_WEAPON_LENGTH + 1]                   = ""
  147.  
  148. new g_HudSync_EndRound
  149. new g_HudSync_SpecInfo
  150.  
  151. //--------------------------------
  152. // Initialize
  153. //--------------------------------
  154. public plugin_init()
  155. {
  156.     // Register plugin.
  157.     register_plugin("StatsX", AMXX_VERSION_STR, "AMXX Dev Team")
  158.     register_dictionary("statsx.txt")
  159.  
  160.     // Register events.
  161.     register_event("TextMsg", "eventStartGame", "a", "2=#Game_Commencing", "2=#Game_will_restart_in")
  162.     register_event("ResetHUD", "eventResetHud", "be")
  163.     register_event("RoundTime", "eventStartRound", "bc")
  164.     register_event("SendAudio", "eventEndRound", "a", "2=%!MRAD_terwin", "2=%!MRAD_ctwin", "2=%!MRAD_rounddraw")
  165.     register_event("TeamScore", "eventTeamScore", "a")
  166.     register_event("30", "eventIntermission", "a")
  167.     register_event("TextMsg", "eventSpecMode", "bd", "2&ec_Mod")
  168.     register_event("StatusValue", "eventShowRank", "bd", "1=2")
  169.  
  170.     // Register commands.
  171.     register_clcmd("say /hp", "cmdHp", 0, "- display info. about your killer (chat)")
  172.     register_clcmd("say /statsme", "cmdStatsMe", 0, "- display your stats (MOTD)")
  173.     register_clcmd("say /rankstats", "cmdRankStats", 0, "- display your server stats (MOTD)")
  174.     register_clcmd("say /me", "cmdMe", 0, "- display current round stats (chat)")
  175.     register_clcmd("say /score", "cmdScore", 0, "- display last score (chat)")
  176.     register_clcmd("say /rank", "cmdRank", 0, "- display your rank (chat)")
  177.     register_clcmd("say /report", "cmdReport", 0, "- display weapon status (say_team)")
  178.     register_clcmd("say /top15", "cmdTop15", 0, "- display top 15 players (MOTD)")
  179.     register_clcmd("say /stats", "cmdStats", 0, "- display players stats (menu/MOTD)")
  180.     register_clcmd("say /switch", "cmdSwitch", 0, "- switch client's stats on or off")
  181.     register_clcmd("say_team /hp", "cmdHp", 0, "- display info. about your killer (chat)")
  182.     register_clcmd("say_team /statsme", "cmdStatsMe", 0, "- display your stats (MOTD)")
  183.     register_clcmd("say_team /rankstats", "cmdRankStats", 0, "- display your server stats (MOTD)")
  184.     register_clcmd("say_team /me", "cmdMe", 0, "- display current round stats (chat)")
  185.     register_clcmd("say_team /score", "cmdScore", 0, "- display last score (chat)")
  186.     register_clcmd("say_team /rank", "cmdRank", 0, "- display your rank (chat)")
  187.     register_clcmd("say_team /report", "cmdReport", 0, "- display weapon status (say_team_team)")
  188.     register_clcmd("say_team /top15", "cmdTop15", 0, "- display top 15 players (MOTD)")
  189.     register_clcmd("say_team /stats", "cmdStats", 0, "- display players stats (menu/MOTD)")
  190.     register_clcmd("say_team /switch", "cmdSwitch", 0, "- switch client's stats on or off")
  191.  
  192.     // Register menus.
  193.     register_menucmd(register_menuid("Server Stats"), 1023, "actionStatsMenu")
  194.  
  195.     // Register special configuration setting and default value.
  196.     register_srvcmd("amx_statsx_mode", "cmdPluginMode", ADMIN_CFG, "<flags> - sets plugin options")
  197.  
  198. #if defined STATSX_DEBUG
  199.     register_clcmd("say /hudtest", "cmdHudTest")
  200. #endif
  201.  
  202.     register_cvar(HUD_DURATION_CVAR, HUD_DURATION)
  203.     register_cvar(HUD_FREEZE_LIMIT_CVAR, HUD_FREEZE_LIMIT)
  204.  
  205.     // Init buffers and some global vars.
  206.     g_sBuffer[0] = 0
  207.     save_team_chatscore()
  208.    
  209.     g_HudSync_EndRound = CreateHudSyncObj()
  210.     g_HudSync_SpecInfo = CreateHudSyncObj()
  211. }
  212.  
  213. public plugin_cfg()
  214. {
  215.     new addStast[] = "amx_statscfg add ^"%s^" %s"
  216.  
  217.     server_cmd(addStast, "ST_SHOW_KILLER_CHAT", "KillerChat")
  218.     server_cmd(addStast, "ST_SHOW_ATTACKERS", "ShowAttackers")
  219.     server_cmd(addStast, "ST_SHOW_VICTIMS", "ShowVictims")
  220.     server_cmd(addStast, "ST_SHOW_KILLER", "ShowKiller")
  221.     server_cmd(addStast, "ST_SHOW_TEAM_SCORE", "ShowTeamScore")
  222.     server_cmd(addStast, "ST_SHOW_TOTAL_STATS", "ShowTotalStats")
  223.     server_cmd(addStast, "ST_SHOW_BEST_SCORE", "ShowBestScore")
  224.     server_cmd(addStast, "ST_SHOW_MOST_DISRUPTIVE", "ShowMostDisruptive")
  225.     server_cmd(addStast, "ST_SHOW_HUD_STATS_DEF", "ShowStats")
  226.     server_cmd(addStast, "ST_SHOW_DIST_HS_HUD", "ShowDistHS")
  227.     server_cmd(addStast, "ST_STATS_PLAYER_MAP_END", "EndPlayer")
  228.     server_cmd(addStast, "ST_STATS_TOP15_MAP_END", "EndTop15")
  229.     server_cmd(addStast, "ST_SAY_HP", "SayHP")
  230.     server_cmd(addStast, "ST_SAY_STATSME", "SayStatsMe")
  231.     server_cmd(addStast, "ST_SAY_RANKSTATS", "SayRankStats")
  232.     server_cmd(addStast, "ST_SAY_ME", "SayMe")
  233.     server_cmd(addStast, "ST_SAY_RANK", "SayRank")
  234.     server_cmd(addStast, "ST_SAY_REPORT", "SayReport")
  235.     server_cmd(addStast, "ST_SAY_SCORE", "SayScore")
  236.     server_cmd(addStast, "ST_SAY_TOP15", "SayTop15")
  237.     server_cmd(addStast, "ST_SAY_STATS", "SayStatsAll")
  238.     server_cmd(addStast, "ST_SPEC_RANK", "SpecRankInfo")
  239.  
  240.     // Update local configuration vars with value in cvars.
  241.     get_config_cvars()
  242. }
  243.  
  244. // Set hudmessage format.
  245. set_hudtype_killer(Float:fDuration)
  246.     set_hudmessage(220, 80, 0, 0.01, 0.14, 0, 6.0, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0, -1)
  247.  
  248. set_hudtype_endround(Float:fDuration)
  249. {
  250.     set_hudmessage(0, 255, 255, 0.01, 0.48, 0, 0.02, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0)
  251. }
  252.  
  253. set_hudtype_attacker(Float:fDuration)
  254.     set_hudmessage(147, 112, 219, 0.78, 0.30, 0, 6.0, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0, -1)
  255.  
  256. set_hudtype_victim(Float:fDuration)
  257.     set_hudmessage(255, 105, 180, 0.78, 0.65, 0, 6.0, fDuration, (fDuration >= g_fHUDDuration) ? 1.0 : 0.0, 1.0, -1)
  258. set_hudtype_specmode()
  259. {
  260.     set_hudmessage(100, 149, 237, 0.02, 0.96, 0, 0.05, 0.1, 0.01, 3.0, -1)
  261. }
  262.  
  263. #if defined STATSX_DEBUG
  264. public cmdHudTest(id)
  265. {
  266.     new i, iLen
  267.     iLen = 0
  268.    
  269.     for (i = 1; i < 20; i++)
  270.         iLen += format(g_sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "....x....1....x....2....x....3....x....4....x....^n")
  271.    
  272.     set_hudtype_killer(50.0)
  273.     show_hudmessage(id, "%s", g_sBuffer)
  274. }
  275. #endif
  276.  
  277. // Stats formulas
  278. Float:accuracy(izStats[8])
  279. {
  280.     if (!izStats[STATS_SHOTS])
  281.         return (0.0)
  282.    
  283.     return (100.0 * float(izStats[STATS_HITS]) / float(izStats[STATS_SHOTS]))
  284. }
  285.  
  286. Float:effec(izStats[8])
  287. {
  288.     if (!izStats[STATS_KILLS])
  289.         return (0.0)
  290.    
  291.     return (100.0 * float(izStats[STATS_KILLS]) / float(izStats[STATS_KILLS] + izStats[STATS_DEATHS]))
  292. }
  293.  
  294. // Distance formula (metric)
  295. Float:distance(iDistance)
  296. {
  297.     return float(iDistance) * 0.0254
  298. }
  299.  
  300. // Get plugin config flags.
  301. set_plugin_mode(id, sFlags[])
  302. {
  303.     if (sFlags[0])
  304.         g_iPluginMode = read_flags(sFlags)
  305.    
  306.     get_flags(g_iPluginMode, t_sText, MAX_TEXT_LENGTH)
  307.     console_print(id, "%L", id, "MODE_SET_TO", t_sText)
  308.    
  309.     return g_iPluginMode
  310. }
  311.  
  312. // Get config parameters.
  313. get_config_cvars()
  314. {
  315.     g_fFreezeTime = get_cvar_float("mp_freezetime")
  316.    
  317.     if (g_fFreezeTime < 0.0)
  318.         g_fFreezeTime = 0.0
  319.  
  320.     g_fHUDDuration = get_cvar_float(HUD_DURATION_CVAR)
  321.    
  322.     if (g_fHUDDuration < 1.0)
  323.         g_fHUDDuration = 1.0
  324.  
  325.     g_fFreezeLimitTime = get_cvar_float(HUD_FREEZE_LIMIT_CVAR)
  326. }
  327.  
  328. // Get and format attackers header and list.
  329. get_attackers(id, sBuffer[MAX_BUFFER_LENGTH + 1])
  330. {
  331.     new izStats[8], izBody[8]
  332.     new iAttacker
  333.     new iFound, iLen
  334.     new iMaxPlayer = get_maxplayers()
  335.  
  336.     iFound = 0
  337.     sBuffer[0] = 0
  338.  
  339.     // Get and format header. Add killing attacker statistics if user is dead.
  340.     // Make sure shots is greater than zero or division by zero will occur.
  341.     // To print a '%', 4 of them must done in a row.
  342.     izStats[STATS_SHOTS] = 0
  343.     iAttacker = g_izKilled[id][KILLED_KILLER_ID]
  344.    
  345.     if (iAttacker)
  346.         get_user_astats(id, iAttacker, izStats, izBody)
  347.    
  348.     if (izStats[STATS_SHOTS] && ShowFullStats)
  349.     {
  350.         get_user_name(iAttacker, t_sName, MAX_NAME_LENGTH)
  351.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L -- %s -- %0.2f%% %L:^n", id, "ATTACKERS", t_sName, accuracy(izStats), id, "ACC")
  352.     }
  353.     else
  354.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L:^n", id, "ATTACKERS")
  355.  
  356.     // Get and format attacker list.
  357.     for (iAttacker = 1; iAttacker <= iMaxPlayer; iAttacker++)
  358.     {
  359.         if (get_user_astats(id, iAttacker, izStats, izBody, t_sWpn, MAX_WEAPON_LENGTH))
  360.         {
  361.             iFound = 1
  362.             get_user_name(iAttacker, t_sName, MAX_NAME_LENGTH)
  363.            
  364.             if (izStats[STATS_KILLS])
  365.             {
  366.                 if (!ShowDistHS)
  367.                     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATS_HITS], id, "HIT_S",
  368.                                     izStats[STATS_DAMAGE], id, "DMG", t_sWpn)
  369.                 else if (izStats[STATS_HS])
  370.                     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATS_HITS], id, "HIT_S",
  371.                                     izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id]))
  372.                 else
  373.                     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATS_HITS], id, "HIT_S",
  374.                                     izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserAttackerDistance[id]))
  375.             }
  376.             else
  377.                 iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATS_HITS], id, "HIT_S", izStats[STATS_DAMAGE], id, "DMG")
  378.         }
  379.     }
  380.    
  381.     if (!iFound)
  382.         sBuffer[0] = 0
  383.    
  384.     return iFound
  385. }
  386.  
  387. // Get and format victims header and list
  388. get_victims(id, sBuffer[MAX_BUFFER_LENGTH + 1])
  389. {
  390.     new izStats[8], izBody[8]
  391.     new iVictim
  392.     new iFound, iLen
  393.     new iMaxPlayer = get_maxplayers()
  394.  
  395.     iFound = 0
  396.     sBuffer[0] = 0
  397.  
  398.     // Get and format header.
  399.     // Make sure shots is greater than zero or division by zero will occur.
  400.     // To print a '%', 4 of them must done in a row.
  401.     izStats[STATS_SHOTS] = 0
  402.     get_user_vstats(id, 0, izStats, izBody)
  403.    
  404.     if (izStats[STATS_SHOTS])
  405.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L -- %0.2f%% %L:^n", id, "VICTIMS", accuracy(izStats), id, "ACC")
  406.     else
  407.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L:^n", id, "VICTIMS")
  408.  
  409.     for (iVictim = 1; iVictim <= iMaxPlayer; iVictim++)
  410.     {
  411.         if (get_user_vstats(id, iVictim, izStats, izBody, t_sWpn, MAX_WEAPON_LENGTH))
  412.         {
  413.             iFound = 1
  414.             get_user_name(iVictim, t_sName, MAX_NAME_LENGTH)
  415.            
  416.             if (izStats[STATS_DEATHS])
  417.             {
  418.                 if (!ShowDistHS)
  419.                     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L / %s^n", t_sName, izStats[STATS_HITS], id, "HIT_S",
  420.                                     izStats[STATS_DAMAGE], id, "DMG", t_sWpn)
  421.                 else if (izStats[STATS_HS])
  422.                     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L / %s / %0.0f m / HS^n", t_sName, izStats[STATS_HITS], id, "HIT_S",
  423.                                     izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim]))
  424.                 else
  425.                     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L / %s / %0.0f m^n", t_sName, izStats[STATS_HITS], id, "HIT_S",
  426.                                     izStats[STATS_DAMAGE], id, "DMG", t_sWpn, distance(g_izUserVictimDistance[id][iVictim]))
  427.             }
  428.             else
  429.                 iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%s -- %d %L / %d %L^n", t_sName, izStats[STATS_HITS], id, "HIT_S", izStats[STATS_DAMAGE], id, "DMG")
  430.         }
  431.     }
  432.    
  433.     if (!iFound)
  434.         sBuffer[0] = 0
  435.  
  436.     return iFound
  437. }
  438.  
  439. // Get and format kill info.
  440. get_kill_info(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1])
  441. {
  442.     new iFound, iLen
  443.  
  444.     iFound = 0
  445.     sBuffer[0] = 0
  446.  
  447.     if (iKiller && iKiller != id)
  448.     {
  449.         new izAStats[8], izABody[8], izVStats[8], iaVBody[8]
  450.  
  451.         iFound = 1
  452.         get_user_name(iKiller, t_sName, MAX_NAME_LENGTH)
  453.  
  454.         izAStats[STATS_HITS] = 0
  455.         izAStats[STATS_DAMAGE] = 0
  456.         t_sWpn[0] = 0
  457.         get_user_astats(id, iKiller, izAStats, izABody, t_sWpn, MAX_WEAPON_LENGTH)
  458.  
  459.         izVStats[STATS_HITS] = 0
  460.         izVStats[STATS_DAMAGE] = 0
  461.         get_user_vstats(id, iKiller, izVStats, iaVBody)
  462.  
  463.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L^n", id, "KILLED_YOU_DIST", t_sName, t_sWpn, distance(g_izUserAttackerDistance[id]))
  464.         iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%L^n", id, "DID_DMG_HITS", izAStats[STATS_DAMAGE], izAStats[STATS_HITS], g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR])
  465.         iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%L^n", id, "YOU_DID_DMG", izVStats[STATS_DAMAGE], izVStats[STATS_HITS])
  466.     }
  467.    
  468.     return iFound
  469. }
  470.  
  471. // Get and format most disruptive.
  472. add_most_disruptive(sBuffer[MAX_BUFFER_LENGTH + 1])
  473. {
  474.     new id, iMaxDamageId, iMaxDamage, iMaxHeadShots
  475.  
  476.     iMaxDamageId = 0
  477.     iMaxDamage = 0
  478.     iMaxHeadShots = 0
  479.  
  480.     // Find player.
  481.     for (id = 1; id < MAX_PLAYERS; id++)
  482.     {
  483.         if (g_izUserRndStats[id][STATS_DAMAGE] >= iMaxDamage && (g_izUserRndStats[id][STATS_DAMAGE] > iMaxDamage || g_izUserRndStats[id][STATS_HS] > iMaxHeadShots))
  484.         {
  485.             iMaxDamageId = id
  486.             iMaxDamage = g_izUserRndStats[id][STATS_DAMAGE]
  487.             iMaxHeadShots = g_izUserRndStats[id][STATS_HS]
  488.         }
  489.     }
  490.  
  491.     // Format statistics.
  492.     if (iMaxDamageId)
  493.     {
  494.         id = iMaxDamageId
  495.        
  496.         new Float:fGameEff = effec(g_izUserGameStats[id])
  497.         new Float:fRndAcc = accuracy(g_izUserRndStats[id])
  498.        
  499.         format(t_sText, MAX_TEXT_LENGTH, "%L: %s^n%d %L / %d %L -- %0.2f%% %L / %0.2f%% %L^n", LANG_SERVER, "MOST_DMG", g_izUserRndName[id],
  500.                 g_izUserRndStats[id][STATS_HITS], LANG_SERVER, "HIT_S", iMaxDamage, LANG_SERVER, "DMG", fGameEff, LANG_SERVER, "EFF", fRndAcc, LANG_SERVER, "ACC")
  501.         add(sBuffer, MAX_BUFFER_LENGTH, t_sText)
  502.     }
  503.    
  504.     return iMaxDamageId
  505. }
  506.  
  507. // Get and format best score.
  508. add_best_score(sBuffer[MAX_BUFFER_LENGTH + 1])
  509. {
  510.     new id, iMaxKillsId, iMaxKills, iMaxHeadShots
  511.  
  512.     iMaxKillsId = 0
  513.     iMaxKills = 0
  514.     iMaxHeadShots = 0
  515.  
  516.     // Find player
  517.     for (id = 1; id < MAX_PLAYERS; id++)
  518.     {
  519.         if (g_izUserRndStats[id][STATS_KILLS] >= iMaxKills && (g_izUserRndStats[id][STATS_KILLS] > iMaxKills || g_izUserRndStats[id][STATS_HS] > iMaxHeadShots))
  520.         {
  521.             iMaxKillsId = id
  522.             iMaxKills = g_izUserRndStats[id][STATS_KILLS]
  523.             iMaxHeadShots = g_izUserRndStats[id][STATS_HS]
  524.         }
  525.     }
  526.  
  527.     // Format statistics.
  528.     if (iMaxKillsId)
  529.     {
  530.         id = iMaxKillsId
  531.        
  532.         new Float:fGameEff = effec(g_izUserGameStats[id])
  533.         new Float:fRndAcc = accuracy(g_izUserRndStats[id])
  534.        
  535.         format(t_sText, MAX_TEXT_LENGTH, "%L: %s^n%d %L / %d hs -- %0.2f%% %L / %0.2f%% %L^n", LANG_SERVER, "BEST_SCORE", g_izUserRndName[id],
  536.                 iMaxKills, LANG_SERVER, "KILL_S", iMaxHeadShots, fGameEff, LANG_SERVER, "EFF", fRndAcc, LANG_SERVER, "ACC")
  537.         add(sBuffer, MAX_BUFFER_LENGTH, t_sText)
  538.     }
  539.    
  540.     return iMaxKillsId
  541. }
  542.  
  543. // Get and format team score.
  544. add_team_score(sBuffer[MAX_BUFFER_LENGTH + 1])
  545. {
  546.     new Float:fzMapEff[MAX_TEAMS], Float:fzMapAcc[MAX_TEAMS], Float:fzRndAcc[MAX_TEAMS]
  547.  
  548.     // Calculate team stats
  549.     for (new iTeam = 0; iTeam < MAX_TEAMS; iTeam++)
  550.     {
  551.         fzMapEff[iTeam] = effec(g_izTeamGameStats[iTeam])
  552.         fzMapAcc[iTeam] = accuracy(g_izTeamGameStats[iTeam])
  553.         fzRndAcc[iTeam] = accuracy(g_izTeamRndStats[iTeam])
  554.     }
  555.  
  556.     // Format round team stats, MOTD
  557.     format(t_sText, MAX_TEXT_LENGTH, "TERRORIST %d / %0.2f%% %L / %0.2f%% %L^nCT %d / %0.2f%% %L / %0.2f%% %L^n", g_izTeamScore[0],
  558.             fzMapEff[0], LANG_SERVER, "EFF", fzRndAcc[0], LANG_SERVER, "ACC", g_izTeamScore[1], fzMapEff[1], LANG_SERVER, "EFF", fzRndAcc[1], LANG_SERVER, "ACC")
  559.     add(sBuffer, MAX_BUFFER_LENGTH, t_sText)
  560. }
  561.  
  562. // Get and format team stats, chat version
  563. save_team_chatscore()
  564. {
  565.     new Float:fzMapEff[MAX_TEAMS], Float:fzMapAcc[MAX_TEAMS], Float:fzRndAcc[MAX_TEAMS]
  566.  
  567.     // Calculate team stats
  568.     for (new iTeam = 0; iTeam < MAX_TEAMS; iTeam++)
  569.     {
  570.         fzMapEff[iTeam] = effec(g_izTeamGameStats[iTeam])
  571.         fzMapAcc[iTeam] = accuracy(g_izTeamGameStats[iTeam])
  572.         fzRndAcc[iTeam] = accuracy(g_izTeamRndStats[iTeam])
  573.     }
  574.  
  575.     // Format game team stats, chat
  576.     format(g_sScore, MAX_BUFFER_LENGTH, "TERRORIST %d / %0.2f%% %L / %0.2f%% %L  --  CT %d / %0.2f%% %L / %0.2f%% %L", g_izTeamScore[0],
  577.             fzMapEff[0], LANG_SERVER, "EFF", fzMapAcc[0], LANG_SERVER, "ACC", g_izTeamScore[1], fzMapEff[1], LANG_SERVER, "EFF", fzMapAcc[1], LANG_SERVER, "ACC")
  578. }
  579.  
  580. // Get and format total stats.
  581. add_total_stats(sBuffer[MAX_BUFFER_LENGTH + 1])
  582. {
  583.     format(t_sText, MAX_TEXT_LENGTH, "%L: %d %L / %d hs -- %d %L / %d %L^n", LANG_SERVER, "TOTAL", g_izUserRndStats[0][STATS_KILLS], LANG_SERVER, "KILL_S",
  584.             g_izUserRndStats[0][STATS_HS], g_izUserRndStats[0][STATS_HITS], LANG_SERVER, "HITS", g_izUserRndStats[0][STATS_SHOTS], LANG_SERVER, "SHOT_S")
  585.     add(sBuffer, MAX_BUFFER_LENGTH, t_sText)
  586. }
  587.  
  588. // Get and format a user's list of body hits from an attacker.
  589. add_attacker_hits(id, iAttacker, sBuffer[MAX_BUFFER_LENGTH + 1])
  590. {
  591.     new iFound = 0
  592.    
  593.     if (iAttacker && iAttacker != id)
  594.     {
  595.         new izStats[8], izBody[8], iLen
  596.  
  597.         izStats[STATS_HITS] = 0
  598.         get_user_astats(id, iAttacker, izStats, izBody)
  599.  
  600.         if (izStats[STATS_HITS])
  601.         {
  602.             iFound = 1
  603.             iLen = strlen(sBuffer)
  604.             get_user_name(iAttacker, t_sName, MAX_NAME_LENGTH)
  605.            
  606.             iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%L:^n", id, "HITS_YOU_IN", t_sName)
  607.            
  608.             for (new i = 1; i < 8; i++)
  609.             {
  610.                 if (!izBody)
  611.                     continue
  612.                
  613.                 iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%L: %d^n", id, BODY_PART, izBody)
  614.             }
  615.         }
  616.     }
  617.    
  618.     return iFound
  619. }
  620.  
  621. // Get and format killed stats: killer hp, ap, hits.
  622. format_kill_ainfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1])
  623. {
  624.     new iFound = 0
  625.    
  626.     if (iKiller && iKiller != id)
  627.     {
  628.         new izStats[8], izBody[8]
  629.         new iLen
  630.        
  631.         iFound = 1
  632.         get_user_name(iKiller, t_sName, MAX_NAME_LENGTH)
  633.         izStats[STATS_HITS] = 0
  634.         get_user_astats(id, iKiller, izStats, izBody, t_sWpn, MAX_WEAPON_LENGTH)
  635.  
  636.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L (%dhp, %dap) >>", id, "KILLED_BY_WITH", t_sName, t_sWpn, distance(g_izUserAttackerDistance[id]),
  637.                         g_izKilled[id][KILLED_KILLER_HEALTH], g_izKilled[id][KILLED_KILLER_ARMOUR])
  638.  
  639.         if (izStats[STATS_HITS])
  640.         {
  641.             for (new i = 1; i < 8; i++)
  642.             {
  643.                 if (!izBody)
  644.                     continue
  645.                
  646.                 iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, " %L: %d", id, BODY_PART, izBody)
  647.             }
  648.         }
  649.         else
  650.             iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, " %L", id, "NO_HITS")
  651.     }
  652.     else
  653.         format(sBuffer, MAX_BUFFER_LENGTH, "%L", id, "YOU_NO_KILLER")
  654.    
  655.     return iFound
  656. }
  657.  
  658. // Get and format killed stats: hits, damage on killer.
  659. format_kill_vinfo(id, iKiller, sBuffer[MAX_BUFFER_LENGTH + 1])
  660. {
  661.     new iFound = 0
  662.     new izStats[8]
  663.     new izBody[8]
  664.     new iLen
  665.  
  666.     izStats[STATS_HITS] = 0
  667.     izStats[STATS_DAMAGE] = 0
  668.     get_user_vstats(id, iKiller, izStats, izBody)
  669.  
  670.     if (iKiller && iKiller != id)
  671.     {
  672.         iFound = 1
  673.         get_user_name(iKiller, t_sName, MAX_NAME_LENGTH)
  674.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L >>", id, "YOU_HIT", t_sName, izStats[STATS_HITS], izStats[STATS_DAMAGE])
  675.     }
  676.     else
  677.         iLen = format(sBuffer, MAX_BUFFER_LENGTH, "%L >>", id, "LAST_RES", izStats[STATS_HITS], izStats[STATS_DAMAGE])
  678.  
  679.     if (izStats[STATS_HITS])
  680.     {
  681.         for (new i = 1; i < 8; i++)
  682.         {
  683.             if (!izBody)
  684.                 continue
  685.            
  686.             iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, " %L: %d", id, BODY_PART, izBody)
  687.         }
  688.     }
  689.     else
  690.         iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, " %L", id, "NO_HITS")
  691.    
  692.     return iFound
  693. }
  694.  
  695. // Get and format top 15.
  696. format_top15(sBuffer[MAX_BUFFER_LENGTH + 1])
  697. {
  698.     new iMax = get_statsnum()
  699.     new izStats[8], izBody[8]
  700.     new iLen = 0
  701.  
  702.     if (iMax > 15)
  703.         iMax = 15
  704.  
  705.     new lKills[16], lDeaths[16], lHits[16], lShots[16], lEff[16], lAcc[16]
  706.    
  707.     format(lKills, 15, "%L", LANG_SERVER, "KILLS")
  708.     format(lDeaths, 15, "%L", LANG_SERVER, "DEATHS")
  709.     format(lHits, 15, "%L", LANG_SERVER, "HITS")
  710.     format(lShots, 15, "%L", LANG_SERVER, "SHOTS")
  711.     format(lEff, 15, "%L", LANG_SERVER, "EFF")
  712.     format(lAcc, 15, "%L", LANG_SERVER, "ACC")
  713.    
  714.     ucfirst(lEff)
  715.     ucfirst(lAcc)
  716.  
  717.     iLen = format(sBuffer, MAX_BUFFER_LENGTH, "<body bgcolor=#000000><font color=#FFB000><pre>")
  718.     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "  %2s %-22.22s %6s %6s  %6s %6s   %4s %4s %3s^n^n", "#", "Nick", lKills, lDeaths, lHits, lShots, "HS", lEff, lAcc)
  719.    
  720.         new iMaxColors = sizeof( g_szTopColors );
  721.    
  722.         for (new i = 0; i < iMax && MAX_BUFFER_LENGTH - iLen > 0; i++)
  723.         {
  724.         get_stats(i, izStats, izBody, t_sName, MAX_NAME_LENGTH)
  725.         replace_all(t_sName, MAX_NAME_LENGTH, "<", "[")
  726.         replace_all(t_sName, MAX_NAME_LENGTH, ">", "]")
  727.        
  728.         if( i < iMaxColors ) {
  729.             iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "=<font color=%s>%2d %-22.22s %6d %6d %6d %6d %5d %4.0f%% %3.0f%%</font>^n", g_szTopColors[ i ], i + 1, t_sName, izStats[STATS_KILLS],
  730.                         izStats[STATS_DEATHS], izStats[STATS_HITS], izStats[STATS_SHOTS], izStats[STATS_HS], effec(izStats), accuracy(izStats))
  731.         } else {
  732.             iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "  %2d %-22.22s %6d %6d %6d %6d %5d %4.0f%% %3.0f%%^n", i + 1, t_sName, izStats[STATS_KILLS],
  733.                         izStats[STATS_DEATHS], izStats[STATS_HITS], izStats[STATS_SHOTS], izStats[STATS_HS], effec(izStats), accuracy(izStats))
  734.         }
  735.     }
  736. }
  737.  
  738. // Get and format rank stats.
  739. format_rankstats(id, sBuffer[MAX_BUFFER_LENGTH + 1], iMyId = 0)
  740. {
  741.     new izStats[8] = {0, ...}
  742.     new izBody[8]
  743.     new iRankPos, iLen
  744.     new lKills[16], lDeaths[16], lHits[16], lShots[16], lDamage[16], lEff[16], lAcc[16]
  745.    
  746.     format(lKills, 15, "%L", id, "KILLS")
  747.     format(lDeaths, 15, "%L", id, "DEATHS")
  748.     format(lHits, 15, "%L", id, "HITS")
  749.     format(lShots, 15, "%L", id, "SHOTS")
  750.     format(lDamage, 15, "%L", id, "DAMAGE")
  751.     format(lEff, 15, "%L", id, "EFF")
  752.     format(lAcc, 15, "%L", id, "ACC")
  753.    
  754.     ucfirst(lEff)
  755.     ucfirst(lAcc)
  756.    
  757.     iRankPos = get_user_stats(id, izStats, izBody)
  758.     iLen = format(sBuffer, MAX_BUFFER_LENGTH, "<body bgcolor=#000000><font color=green><pre>")
  759.     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%L %L^n^n", id, (!iMyId || iMyId == id) ? "YOUR" : "PLAYERS", id, "RANK_IS", iRankPos, get_statsnum())
  760.     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%6s: %d  (%d with hs)^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %0.2f%%^n%6s: %0.2f%%^n^n",
  761.                     lKills, izStats[STATS_KILLS], izStats[STATS_HS], lDeaths, izStats[STATS_DEATHS], lHits, izStats[STATS_HITS], lShots, izStats[STATS_SHOTS],
  762.                     lDamage, izStats[STATS_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
  763.    
  764.     new L_BODY_PART[8][32]
  765.    
  766.     for (new i = 1; i < 8; i++)
  767.     {
  768.         format(L_BODY_PART, 31, "%L", id, BODY_PART[i])
  769.     }
  770.    
  771.     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%10s:^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d^n%10s: %d", "HITS",
  772.                     L_BODY_PART[1], izBody[1], L_BODY_PART[2], izBody[2], L_BODY_PART[3], izBody[3], L_BODY_PART[4], izBody[4], L_BODY_PART[5],
  773.                     izBody[5], L_BODY_PART[6], izBody[6], L_BODY_PART[7], izBody[7])
  774. }
  775.  
  776. // Get and format stats.
  777. format_stats(id, sBuffer[MAX_BUFFER_LENGTH + 1])
  778. {
  779.     new izStats[8] = {0, ...}
  780.     new izBody[8]
  781.     new iWeapon, iLen
  782.     new lKills[16], lDeaths[16], lHits[16], lShots[16], lDamage[16], lEff[16], lAcc[16], lWeapon[16]
  783.    
  784.     format(lKills, 15, "%L", id, "KILLS")
  785.     format(lDeaths, 15, "%L", id, "DEATHS")
  786.     format(lHits, 15, "%L", id, "HITS")
  787.     format(lShots, 15, "%L", id, "SHOTS")
  788.     format(lDamage, 15, "%L", id, "DAMAGE")
  789.     format(lEff, 15, "%L", id, "EFF")
  790.     format(lAcc, 15, "%L", id, "ACC")
  791.     format(lWeapon, 15, "%L", id, "WEAPON")
  792.    
  793.     ucfirst(lEff)
  794.     ucfirst(lAcc)
  795.    
  796.     get_user_wstats(id, 0, izStats, izBody)
  797.    
  798.     iLen = format(sBuffer, MAX_BUFFER_LENGTH, "<body bgcolor=#000000><font color=green><pre>")
  799.     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%6s: %d  (%d with hs)^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %d^n%6s: %0.2f%%^n%6s: %0.2f%%^n^n",
  800.                     lKills, izStats[STATS_KILLS], izStats[STATS_HS], lDeaths, izStats[STATS_DEATHS], lHits, izStats[STATS_HITS], lShots, izStats[STATS_SHOTS],
  801.                     lDamage, izStats[STATS_DAMAGE], lEff, effec(izStats), lAcc, accuracy(izStats))
  802.     iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%-12.12s  %6s  %6s  %6s  %6s  %6s  %4s^n", lWeapon, lKills, lDeaths, lHits, lShots, lDamage, lAcc)
  803.    
  804.     for (iWeapon = 1; iWeapon < xmod_get_maxweapons() && MAX_BUFFER_LENGTH - iLen > 0 ; iWeapon++)
  805.     {
  806.         if (get_user_wstats(id, iWeapon, izStats, izBody))
  807.         {
  808.             xmod_get_wpnname(iWeapon, t_sWpn, MAX_WEAPON_LENGTH)
  809.             iLen += format(sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%-12.12s  %6d  %6d  %6d  %6d  %6d  %3.0f%%^n", t_sWpn, izStats[STATS_KILLS], izStats[STATS_DEATHS],
  810.                             izStats[STATS_HITS], izStats[STATS_SHOTS], izStats[STATS_DAMAGE], accuracy(izStats))
  811.         }
  812.     }
  813. }
  814.  
  815. // Show round end stats. If gametime is zero then use default duration time.
  816. show_roundend_hudstats(id, Float:fGameTime)
  817. {
  818.     // Bail out if there no HUD stats should be shown
  819.     // for this player or end round stats not created.
  820.     if (!g_izStatsSwitch[id]) return
  821.     if (!g_sAwardAndScore[0]) return
  822.  
  823.     // If round end timer is zero clear round end stats.
  824.     if (g_fShowStatsTime == 0.0)
  825.     {
  826.         ClearSyncHud(id, g_HudSync_EndRound)
  827. #if defined STATSX_DEBUG
  828.         log_amx("Clear round end HUD stats for #%d", id)
  829. #endif
  830.     }
  831.  
  832.     // Set HUD-duration to default or remaining time.
  833.     new Float:fDuration
  834.    
  835.     if (fGameTime == 0.0)
  836.         fDuration = g_fHUDDuration
  837.     else
  838.     {
  839.         fDuration = g_fShowStatsTime + g_fHUDDuration - fGameTime
  840.        
  841.         if (fDuration > g_fFreezeTime + g_fFreezeLimitTime)
  842.             fDuration = g_fFreezeTime + g_fFreezeLimitTime
  843.     }
  844.    
  845.     // Show stats only if more time left than coded minimum.
  846.     if (fDuration >= HUD_MIN_DURATION)
  847.     {
  848.         set_hudtype_endround(fDuration)
  849.         ShowSyncHudMsg(id, g_HudSync_EndRound, "%s", g_sAwardAndScore)
  850. #if defined STATSX_DEBUG
  851.         log_amx("Show %1.2fs round end HUD stats for #%d", fDuration, id)
  852. #endif
  853.     }
  854. }
  855.  
  856. // Show round end stats.
  857. show_user_hudstats(id, Float:fGameTime)
  858. {
  859.     // Bail out if there no HUD stats should be shown
  860.     // for this player or user stats timer is zero.
  861.     if (!g_izStatsSwitch[id]) return
  862.     if (g_fzShowUserStatsTime[id] == 0.0) return
  863.  
  864.     // Set HUD-duration to default or remaining time.
  865.     new Float:fDuration
  866.    
  867.     if (fGameTime == 0.0)
  868.         fDuration = g_fHUDDuration
  869.     else
  870.     {
  871.         fDuration = g_fzShowUserStatsTime[id] + g_fHUDDuration - fGameTime
  872.        
  873.         if (fDuration > g_fFreezeTime + g_fFreezeLimitTime)
  874.             fDuration = g_fFreezeTime + g_fFreezeLimitTime
  875.     }
  876.  
  877.     // Show stats only if more time left than coded minimum.
  878.     if (fDuration >= HUD_MIN_DURATION)
  879.     {
  880.         if (ShowKiller)
  881.         {
  882.             new iKiller
  883.            
  884.             iKiller = g_izKilled[id][KILLED_KILLER_ID]
  885.             get_kill_info(id, iKiller, g_sBuffer)
  886.             add_attacker_hits(id, iKiller, g_sBuffer)
  887.             set_hudtype_killer(fDuration)
  888.             show_hudmessage(id, "%s", g_sBuffer)
  889. #if defined STATSX_DEBUG
  890.             log_amx("Show %1.2fs %suser HUD k-stats for #%d", fDuration, g_sBuffer[0] ? "" : "no ", id)
  891. #endif
  892.         }
  893.        
  894.         if (ShowVictims)
  895.         {
  896.             get_victims(id, g_sBuffer)
  897.             set_hudtype_victim(fDuration)
  898.             show_hudmessage(id, "%s", g_sBuffer)
  899. #if defined STATSX_DEBUG
  900.             log_amx("Show %1.2fs %suser HUD v-stats for #%d", fDuration, g_sBuffer[0] ? "" : "no ", id)
  901. #endif
  902.         }
  903.        
  904.         if (ShowAttackers)
  905.         {
  906.             get_attackers(id, g_sBuffer)
  907.             set_hudtype_attacker(fDuration)
  908.             show_hudmessage(id, "%s", g_sBuffer)
  909. #if defined STATSX_DEBUG
  910.             log_amx("Show %1.2fs %suser HUD a-stats for #%d", fDuration, g_sBuffer[0] ? "" : "no ", id)
  911. #endif
  912.         }
  913.     }
  914. }
  915.  
  916. //------------------------------------------------------------
  917. // Plugin commands
  918. //------------------------------------------------------------
  919.  
  920. // Set or get plugin config flags.
  921. public cmdPluginMode(id, level, cid)
  922. {
  923.     if (!cmd_access(id, level, cid, 1))
  924.         return PLUGIN_HANDLED
  925.    
  926.     if (read_argc() > 1)
  927.         read_argv(1, g_sBuffer, MAX_BUFFER_LENGTH)
  928.     else
  929.         g_sBuffer[0] = 0
  930.    
  931.     set_plugin_mode(id, g_sBuffer)
  932.    
  933.     return PLUGIN_HANDLED
  934. }
  935.  
  936. // Display MOTD stats.
  937. public cmdStatsMe(id)
  938. {
  939.     if (!SayStatsMe)
  940.     {
  941.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  942.         return PLUGIN_HANDLED
  943.     }
  944.  
  945.     format_stats(id, g_sBuffer)
  946.     get_user_name(id, t_sName, MAX_NAME_LENGTH)
  947.     show_motd(id, g_sBuffer, t_sName)
  948.    
  949.     return PLUGIN_CONTINUE
  950. }
  951.  
  952. // Display MOTD rank.
  953. public cmdRankStats(id)
  954. {
  955.     if (!SayRankStats)
  956.     {
  957.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  958.         return PLUGIN_HANDLED
  959.     }
  960.    
  961.     format_rankstats(id, g_sBuffer)
  962.     get_user_name(id, t_sName, MAX_NAME_LENGTH)
  963.     show_motd(id, g_sBuffer, t_sName)
  964.    
  965.     return PLUGIN_CONTINUE
  966. }
  967.  
  968. // Display MOTD top15 ranked.
  969. public cmdTop15(id)
  970. {
  971.     if (!SayTop15)
  972.     {
  973.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  974.         return PLUGIN_HANDLED
  975.     }
  976.    
  977.     format_top15(g_sBuffer)
  978.     show_motd(id, g_sBuffer, "Top 15")
  979.    
  980.     return PLUGIN_CONTINUE
  981. }
  982.  
  983. // Display killer information.
  984. public cmdHp(id)
  985. {
  986.     if (!SayHP)
  987.     {
  988.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  989.         return PLUGIN_HANDLED
  990.     }
  991.    
  992.     new iKiller = g_izKilled[id][KILLED_KILLER_ID]
  993.    
  994.     format_kill_ainfo(id, iKiller, g_sBuffer)
  995.     client_print(id, print_chat, "* %s", g_sBuffer)
  996.    
  997.     return PLUGIN_CONTINUE
  998. }
  999.  
  1000. // Display user stats.
  1001. public cmdMe(id)
  1002. {
  1003.     if (!SayMe)
  1004.     {
  1005.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  1006.         return PLUGIN_HANDLED
  1007.     }
  1008.    
  1009.     format_kill_vinfo(id, 0, g_sBuffer)
  1010.     client_print(id, print_chat, "* %s", g_sBuffer)
  1011.    
  1012.     return PLUGIN_CONTINUE
  1013. }
  1014.  
  1015. // Display user rank
  1016. public cmdRank(id)
  1017. {
  1018.     if (!SayRank)
  1019.     {
  1020.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  1021.         return PLUGIN_HANDLED
  1022.     }
  1023.  
  1024.     new izStats[8], izBody[8]
  1025.     new iRankPos, iRankMax
  1026.     new Float:fEff, Float:fAcc
  1027.    
  1028.     iRankPos = get_user_stats(id, izStats, izBody)
  1029.     iRankMax = get_statsnum()
  1030.    
  1031.     fEff = effec(izStats)
  1032.     fAcc = accuracy(izStats)
  1033.    
  1034.     client_print(id, print_chat, "* %L", id, "YOUR_RANK_IS", iRankPos, iRankMax, izStats[STATS_KILLS], izStats[STATS_HITS], fEff, fAcc)
  1035.    
  1036.     return PLUGIN_CONTINUE
  1037. }
  1038.  
  1039. // Report user weapon status to team.
  1040. public cmdReport(id)
  1041. {
  1042.     if (!SayReport)
  1043.     {
  1044.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  1045.         return PLUGIN_HANDLED
  1046.     }
  1047.    
  1048.     new iWeapon, iClip, iAmmo, iHealth, iArmor
  1049.    
  1050.     iWeapon = get_user_weapon(id, iClip, iAmmo)
  1051.    
  1052.     if (iWeapon != 0)
  1053.         xmod_get_wpnname(iWeapon, t_sWpn, MAX_WEAPON_LENGTH)
  1054.    
  1055.     iHealth = get_user_health(id)
  1056.     iArmor = get_user_armor(id)
  1057.    
  1058.     new lWeapon[16]
  1059.    
  1060.     format(lWeapon, 15, "%L", id, "WEAPON")
  1061.     strtolower(lWeapon)
  1062.    
  1063.     if (iClip >= 0)
  1064.     {
  1065.         format(g_sBuffer, MAX_BUFFER_LENGTH, "%s: %s, %L: %d/%d, %L: %d, %L: %d", lWeapon, t_sWpn, LANG_SERVER, "AMMO", iClip, iAmmo, LANG_SERVER, "HEALTH", iHealth, LANG_SERVER, "ARMOR", iArmor)
  1066.     }
  1067.     else
  1068.         format(g_sBuffer, MAX_BUFFER_LENGTH, "%s: %s, %L: %d, %L: %d", lWeapon, t_sWpn[7], LANG_SERVER, "HEALTH", iHealth, LANG_SERVER, "ARMOR", iArmor)
  1069.    
  1070.     engclient_cmd(id, "say_team", g_sBuffer)
  1071.    
  1072.     return PLUGIN_CONTINUE
  1073. }
  1074.  
  1075. // Display team map score
  1076. public cmdScore(id)
  1077. {
  1078.     if (!SayScore)
  1079.     {
  1080.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  1081.         return PLUGIN_HANDLED
  1082.     }
  1083.    
  1084.     client_print(id, print_chat, "%L: %s", id, "GAME_SCORE", g_sScore)
  1085.    
  1086.     return PLUGIN_CONTINUE
  1087. }
  1088.  
  1089. // Client switch to enable or disable stats announcements.
  1090. public cmdSwitch(id)
  1091. {
  1092.     g_izStatsSwitch[id] = (g_izStatsSwitch[id]) ? 0 : -1
  1093.     num_to_str(g_izStatsSwitch[id], t_sText, MAX_TEXT_LENGTH)
  1094.     client_cmd(id, "setinfo _amxstatsx %s", t_sText)
  1095.    
  1096.     new lEnDis[32]
  1097.    
  1098.     format(lEnDis, 31, "%L", id, g_izStatsSwitch[id] ? "ENABLED" : "DISABLED")
  1099.     client_print(id, print_chat, "* %L", id, "STATS_ANNOUNCE", lEnDis)
  1100.    
  1101.     return PLUGIN_CONTINUE
  1102. }
  1103.  
  1104. // Player stats menu.
  1105. public cmdStats(id)
  1106. {
  1107.     if (!SayStatsAll)
  1108.     {
  1109.         client_print(id, print_chat, "%L", id, "DISABLED_MSG")
  1110.         return PLUGIN_HANDLED
  1111.     }
  1112.    
  1113.     showStatsMenu(id, g_izUserMenuPosition[id] = 0)
  1114.    
  1115.     return PLUGIN_CONTINUE
  1116. }
  1117.  
  1118. //--------------------------------
  1119. // Menu
  1120. //--------------------------------
  1121.  
  1122. public actionStatsMenu(id, key)
  1123. {
  1124.     switch (key)
  1125.     {
  1126.         // Key '1' to '7', execute action on this option
  1127.         case 0..6:
  1128.         {
  1129.             new iOption, iIndex
  1130.             iOption = (g_izUserMenuPosition[id] * PPL_MENU_OPTIONS) + key
  1131.            
  1132.             if (iOption >= 0 && iOption < 32)
  1133.             {
  1134.                 iIndex = g_izUserMenuPlayers[id][iOption]
  1135.            
  1136.                 if (is_user_connected(iIndex))
  1137.                 {
  1138.                     switch (g_izUserMenuAction[id])
  1139.                     {
  1140.                         case 0: format_stats(iIndex, g_sBuffer)
  1141.                         case 1: format_rankstats(iIndex, g_sBuffer, id)
  1142.                         default: g_sBuffer[0] = 0
  1143.                     }
  1144.                    
  1145.                     if (g_sBuffer[0])
  1146.                     {
  1147.                         get_user_name(iIndex, t_sName, MAX_NAME_LENGTH)
  1148.                         show_motd(id, g_sBuffer, t_sName)
  1149.                     }
  1150.                 }
  1151.             }
  1152.            
  1153.             showStatsMenu(id, g_izUserMenuPosition[id])
  1154.         }
  1155.         // Key '8', change action
  1156.         case 7:
  1157.         {
  1158.             g_izUserMenuAction[id]++
  1159.            
  1160.             if (g_izUserMenuAction[id] >= MAX_PPL_MENU_ACTIONS)
  1161.                 g_izUserMenuAction[id] = 0
  1162.            
  1163.             showStatsMenu(id, g_izUserMenuPosition[id])
  1164.         }
  1165.         // Key '9', select next page of options
  1166.         case 8: showStatsMenu(id, ++g_izUserMenuPosition[id])
  1167.         // Key '10', cancel or go back to previous menu
  1168.         case 9:
  1169.         {
  1170.             if (g_izUserMenuPosition[id] > 0)
  1171.                 showStatsMenu(id, --g_izUserMenuPosition[id])
  1172.         }
  1173.     }
  1174.    
  1175.     return PLUGIN_HANDLED
  1176. }
  1177.  
  1178. new g_izUserMenuActionText[MAX_PPL_MENU_ACTIONS][] = {"Show stats", "Show rank stats"}
  1179.  
  1180. showStatsMenu(id, iMenuPos)
  1181. {
  1182.     new iLen, iKeyMask, iPlayers
  1183.     new iUserIndex, iMenuPosMax, iMenuOption, iMenuOptionMax
  1184.    
  1185.     get_players(g_izUserMenuPlayers[id], iPlayers)
  1186.     iMenuPosMax = ((iPlayers - 1) / PPL_MENU_OPTIONS) + 1
  1187.    
  1188.     // If menu pos does not excist use last menu (if players has left)
  1189.     if (iMenuPos >= iMenuPosMax)
  1190.         iMenuPos = iMenuPosMax - 1
  1191.  
  1192.     iUserIndex = iMenuPos * PPL_MENU_OPTIONS
  1193.     iLen = format(g_sBuffer, MAX_BUFFER_LENGTH, "\y%L\R%d/%d^n\w^n", id, "SERVER_STATS", iMenuPos + 1, iMenuPosMax)
  1194.     iMenuOptionMax = iPlayers - iUserIndex
  1195.    
  1196.     if (iMenuOptionMax > PPL_MENU_OPTIONS)
  1197.         iMenuOptionMax = PPL_MENU_OPTIONS
  1198.    
  1199.     for (iMenuOption = 0; iMenuOption < iMenuOptionMax; iMenuOption++)
  1200.     {
  1201.         get_user_name(g_izUserMenuPlayers[id][iUserIndex++], t_sName, MAX_NAME_LENGTH)
  1202.         iKeyMask |= (1<<iMenuOption)
  1203.         iLen += format(g_sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "%d. %s^n\w", iMenuOption + 1, t_sName)
  1204.     }
  1205.    
  1206.     iKeyMask |= MENU_KEY_8|MENU_KEY_0
  1207.     iLen += format(g_sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "^n8. %s^n\w", g_izUserMenuActionText[g_izUserMenuAction[id]])
  1208.    
  1209.     if (iPlayers > iUserIndex)
  1210.     {
  1211.         iLen += format(g_sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "^n9. %L...", id, "MORE")
  1212.         iKeyMask |= MENU_KEY_9
  1213.     }
  1214.    
  1215.     if (iMenuPos > 0)
  1216.         iLen += format(g_sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "^n0. %L", id, "BACK")
  1217.     else
  1218.         iLen += format(g_sBuffer[iLen], MAX_BUFFER_LENGTH - iLen, "^n0. %L", id, "EXIT")
  1219.    
  1220.     show_menu(id, iKeyMask, g_sBuffer, -1, "Server Stats")
  1221.    
  1222.     return PLUGIN_HANDLED
  1223. }
  1224.  
  1225. //------------------------------------------------------------
  1226. // Plugin events
  1227. //------------------------------------------------------------
  1228.  
  1229. // Reset game stats on game start and restart.
  1230. public eventStartGame()
  1231. {
  1232.     read_data(2, t_sText, MAX_TEXT_LENGTH)
  1233.    
  1234.     if (t_sText[6] == 'w')
  1235.     {
  1236.         read_data(3, t_sText, MAX_TEXT_LENGTH)
  1237.         g_fStartGame = get_gametime() + float(str_to_num(t_sText))
  1238.     }
  1239.     else
  1240.         g_fStartGame = get_gametime()
  1241.    
  1242.     return PLUGIN_CONTINUE
  1243. }
  1244.  
  1245. // Round start
  1246. public eventStartRound()
  1247. {
  1248.     new iTeam, id, i
  1249.    
  1250.     new Float:roundtime = get_cvar_float("mp_roundtime");
  1251.     if (read_data(1) >= floatround(roundtime * 60.0,floatround_floor) || (roundtime == 2.3 && read_data(1) == 137)) // these round too weird for it to work through pawn, have to add an exception for it
  1252.     {
  1253. #if defined STATSX_DEBUG
  1254.         log_amx("Reset round stats")
  1255. #endif
  1256.        
  1257.         // Reset game stats on game start and restart.
  1258.         if (g_fStartGame > 0.0 && g_fStartGame <= get_gametime())
  1259.         {
  1260. #if defined STATSX_DEBUG
  1261.             log_amx("Reset game stats")
  1262. #endif
  1263.             g_fStartGame = 0.0
  1264.  
  1265.             // Clear team and game stats.
  1266.             for (iTeam = 0; iTeam < MAX_TEAMS; iTeam++)
  1267.             {
  1268.                 g_izTeamEventScore[iTeam] = 0
  1269.                
  1270.                 for (i = 0; i < 8; i++)
  1271.                     g_izTeamGameStats[iTeam][i] = 0
  1272.             }
  1273.  
  1274.             // Clear game stats, incl '0' that is sum of all users.
  1275.             for (id = 0; id < MAX_PLAYERS; id++)
  1276.             {
  1277.                 for (i = 0; i < 8; i++)
  1278.                     g_izUserGameStats[id][i] = 0
  1279.             }
  1280.         }
  1281.  
  1282.         // Update team score with "TeamScore" event values and
  1283.         // clear team round stats.
  1284.         for (iTeam = 0; iTeam < MAX_TEAMS; iTeam++)
  1285.         {
  1286.             g_izTeamScore[iTeam] = g_izTeamEventScore[iTeam]
  1287.            
  1288.             for (i = 0; i < 8; i++)
  1289.                 g_izTeamRndStats[iTeam][i] = 0
  1290.         }
  1291.  
  1292.         // Clear user round stats, incl '0' that is sum of all users.
  1293.         for (id = 0; id < MAX_PLAYERS; id++)
  1294.         {
  1295.             g_izUserRndName[id][0] = 0
  1296.            
  1297.             for (i = 0; i < 8; i++)
  1298.                 g_izUserRndStats[id][i] = 0
  1299.            
  1300.             g_fzShowUserStatsTime[id] = 0.0
  1301.         }
  1302.  
  1303.         // Allow end round stats and reset end round triggered indicator.
  1304.         g_iRoundEndTriggered = 0
  1305.         g_iRoundEndProcessed = 0
  1306.         g_fShowStatsTime = 0.0
  1307.  
  1308.         // Update local configuration vars with value in cvars.
  1309.         get_config_cvars()
  1310.     }
  1311.  
  1312.     return PLUGIN_CONTINUE
  1313. }
  1314.  
  1315. // Reset killer info on round restart.
  1316. public eventResetHud(id)
  1317. {
  1318.     new args[1]
  1319.     args[0] = id
  1320.    
  1321.     if (g_iPluginMode & MODE_HUD_DELAY)
  1322.         set_task(0.01, "delay_resethud", 200 + id, args, 1)
  1323.     else
  1324.         delay_resethud(args)
  1325.    
  1326.     return PLUGIN_CONTINUE
  1327. }
  1328.  
  1329. public delay_resethud(args[])
  1330. {
  1331.     new id = args[0]
  1332.     new Float:fGameTime
  1333.  
  1334.     // Show user and score round stats after HUD-reset
  1335. #if defined STATSX_DEBUG
  1336.     log_amx("Reset HUD for #%d", id)
  1337. #endif
  1338.     fGameTime = get_gametime()
  1339.     show_user_hudstats(id, fGameTime)
  1340.     show_roundend_hudstats(id, fGameTime)
  1341.  
  1342.     // Reset round stats
  1343.     g_izKilled[id][KILLED_KILLER_ID] = 0
  1344.     g_izKilled[id][KILLED_KILLER_STATSFIX] = 0
  1345.     g_izShowStatsFlags[id] = -1     // Initialize flags
  1346.     g_fzShowUserStatsTime[id] = 0.0
  1347.     g_izUserAttackerDistance[id] = 0
  1348.    
  1349.     for (new i = 0; i < MAX_PLAYERS; i++)
  1350.         g_izUserVictimDistance[id][i] = 0
  1351.    
  1352.     return PLUGIN_CONTINUE
  1353. }
  1354.  
  1355. // Save killer info on death.
  1356. public client_death(killer, victim, wpnindex, hitplace, TK)
  1357. {
  1358.     // Bail out if no killer.
  1359.     if (!killer)
  1360.         return PLUGIN_CONTINUE
  1361.  
  1362.     if (killer != victim)
  1363.     {
  1364.         new iaVOrigin[3], iaKOrigin[3]
  1365.         new iDistance
  1366.        
  1367.         get_user_origin(victim, iaVOrigin)
  1368.         get_user_origin(killer, iaKOrigin)
  1369.        
  1370.         g_izKilled[victim][KILLED_KILLER_ID] = killer
  1371.         g_izKilled[victim][KILLED_KILLER_HEALTH] = get_user_health(killer)
  1372.         g_izKilled[victim][KILLED_KILLER_ARMOUR] = get_user_armor(killer)
  1373.         g_izKilled[victim][KILLED_KILLER_STATSFIX] = 0
  1374.  
  1375.         iDistance = get_distance(iaVOrigin, iaKOrigin)
  1376.         g_izUserAttackerDistance[victim] = iDistance
  1377.         g_izUserVictimDistance[killer][victim] = iDistance
  1378.     }
  1379.    
  1380.     g_izKilled[victim][KILLED_TEAM] = get_user_team(victim)
  1381.     g_izKilled[victim][KILLED_KILLER_STATSFIX] = 1
  1382.  
  1383.     // Display kill stats for the player if round
  1384.     // end stats was not processed.
  1385.     if (!g_iRoundEndProcessed)
  1386.         kill_stats(victim)
  1387.  
  1388.     return PLUGIN_CONTINUE
  1389. }
  1390.  
  1391. // Display hudmessage stats on death.
  1392. // This will also update all round and game stats.
  1393. // Must be called at least once per round.
  1394. kill_stats(id)
  1395. {
  1396.     // Bail out if user stats timer is non-zero,
  1397.     // ie function already called.
  1398.     if (g_fzShowUserStatsTime[id] > 0.0)
  1399.     {
  1400.         return
  1401.     }
  1402.        
  1403.     new team = get_user_team(id)
  1404.     if (team < 1 || team > 2)
  1405.     {
  1406.         return
  1407.     }
  1408.  
  1409.     // Flag kill stats displayed for this player.
  1410.     g_fzShowUserStatsTime[id] = get_gametime()
  1411.  
  1412.     // Add user death stats to user round stats
  1413.     new izStats[8], izBody[8]
  1414.     new iTeam, i
  1415.     new iKiller
  1416.  
  1417.     iKiller = g_izKilled[id][KILLED_KILLER_ID]
  1418.  
  1419.     // Get user's team (if dead use the saved team)
  1420.     if (iKiller)
  1421.         iTeam = g_izKilled[id][KILLED_TEAM] - 1
  1422.     else
  1423.         iTeam = get_user_team(id) - 1
  1424.  
  1425.     get_user_name(id, g_izUserRndName[id], MAX_NAME_LENGTH)
  1426.  
  1427.     if (get_user_rstats(id, izStats, izBody))
  1428.     {
  1429.         // Update user's team round stats
  1430.         if (iTeam >= 0 && iTeam < MAX_TEAMS)
  1431.         {
  1432.             for (i = 0; i < 8; i++)
  1433.             {
  1434.                 g_izTeamRndStats[iTeam][i] += izStats[i]
  1435.                 g_izTeamGameStats[iTeam][i] += izStats[i]
  1436.                 g_izUserRndStats[0][i] += izStats[i]
  1437.                 g_izUserGameStats[0][i] += izStats[i]
  1438.             }
  1439.         }
  1440.  
  1441.         // Update user's round stats
  1442.         if (g_izUserUserID[id] == get_user_userid(id))
  1443.         {
  1444.             for (i = 0; i < 8; i++)
  1445.             {
  1446.                 g_izUserRndStats[id][i] += izStats[i]
  1447.                 g_izUserGameStats[id][i] += izStats[i]
  1448.             }
  1449.         } else {
  1450.             g_izUserUserID[id] = get_user_userid(id)
  1451.            
  1452.             for (i = 0; i < 8; i++)
  1453.             {
  1454.                 g_izUserRndStats[id][i] = izStats[i]
  1455.                 g_izUserGameStats[id][i] = izStats[i]
  1456.             }
  1457.         }
  1458.  
  1459.     }   // endif (get_user_rstats())
  1460.  
  1461.     // Report stats in the chat section, if player is killed.
  1462.     if (KillerChat && iKiller && iKiller != id)
  1463.     {
  1464.         if (format_kill_ainfo(id, iKiller, g_sBuffer))
  1465.         {
  1466.             client_print(id, print_chat, "* %s", g_sBuffer)
  1467.             format_kill_vinfo(id, iKiller, g_sBuffer)
  1468.         }
  1469.        
  1470.         client_print(id, print_chat, "* %s", g_sBuffer)
  1471.     }
  1472.  
  1473.     // Display player stats info.
  1474. #if defined STATSX_DEBUG
  1475.     log_amx("Kill stats for #%d", id)
  1476. #endif
  1477.     show_user_hudstats(id, 0.0)
  1478. }
  1479.  
  1480. public eventEndRound()
  1481. {
  1482.     // Update local configuration vars with value in cvars.
  1483.     get_config_cvars()
  1484.  
  1485.     // If first end round event in the round, calculate team score.
  1486.     if (!g_iRoundEndTriggered)
  1487.     {
  1488.         read_data(2, t_sText, MAX_TEXT_LENGTH)
  1489.        
  1490.         if (t_sText[7] == 't')          // Terrorist wins
  1491.             g_izTeamScore[0]++
  1492.         else if (t_sText[7] == 'c')     // CT wins
  1493.             g_izTeamScore[1]++
  1494.     }
  1495.  
  1496.     set_task(0.3, "ERTask", 997)
  1497.    
  1498.     return PLUGIN_CONTINUE
  1499. }
  1500.  
  1501. public ERTask()
  1502. {
  1503.     // Flag round end triggered.
  1504.     g_iRoundEndTriggered = 1
  1505.  
  1506.     // Display round end stats to all players.
  1507.     endround_stats()
  1508. }
  1509.  
  1510. endround_stats()
  1511. {
  1512.     // Bail out if end round stats has already been processed
  1513.     // or round end not triggered.
  1514.     if (g_iRoundEndProcessed || !g_iRoundEndTriggered)
  1515.         return
  1516.  
  1517.     new iaPlayers[32], iPlayer, iPlayers, id
  1518.  
  1519.     get_players(iaPlayers, iPlayers)
  1520.  
  1521.     // Display attacker & victim list for all living players.
  1522.     // This will also update all round and game stats for all players
  1523.     // not killed.
  1524. #if defined STATSX_DEBUG
  1525.     log_amx("End round stats")
  1526. #endif
  1527.    
  1528.     for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
  1529.     {
  1530.         id = iaPlayers[iPlayer]
  1531.        
  1532.         if (g_fzShowUserStatsTime[id] == 0.0)
  1533.         {
  1534.             kill_stats(id)
  1535.         }
  1536.     }
  1537.  
  1538.     g_sAwardAndScore[0] = 0
  1539.  
  1540.     // Create round awards.
  1541.     if (ShowMostDisruptive)
  1542.         add_most_disruptive(g_sAwardAndScore)
  1543.     if (ShowBestScore)
  1544.         add_best_score(g_sAwardAndScore)
  1545.  
  1546.     // Create round score.
  1547.     // Compensate HUD message if awards are disabled.
  1548.     if (ShowTeamScore || ShowTotalStats)
  1549.     {
  1550.         if (ShowMostDisruptive && ShowBestScore)
  1551.             add(g_sAwardAndScore, MAX_BUFFER_LENGTH, "^n^n")
  1552.         else if (ShowMostDisruptive || ShowBestScore)
  1553.             add(g_sAwardAndScore, MAX_BUFFER_LENGTH, "^n^n^n^n")
  1554.         else
  1555.             add(g_sAwardAndScore, MAX_BUFFER_LENGTH, "^n^n^n^n^n^n")
  1556.  
  1557.         if (ShowTeamScore)
  1558.             add_team_score(g_sAwardAndScore)
  1559.        
  1560.         if (ShowTotalStats)
  1561.             add_total_stats(g_sAwardAndScore)
  1562.     }
  1563.  
  1564.     save_team_chatscore()
  1565.  
  1566.     // Get and save round end stats time.
  1567.     g_fShowStatsTime = get_gametime()
  1568.  
  1569.     // Display round end stats to all players.
  1570.     for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
  1571.     {
  1572.         id = iaPlayers[iPlayer]
  1573.         show_roundend_hudstats(id, 0.0)
  1574.     }
  1575.  
  1576.     // Flag round end processed.
  1577.     g_iRoundEndProcessed = 1
  1578. }
  1579.  
  1580. public eventTeamScore()
  1581. {
  1582.     new sTeamID[1 + 1], iTeamScore
  1583.     read_data(1, sTeamID, 1)
  1584.     iTeamScore = read_data(2)
  1585.     g_izTeamEventScore[(sTeamID[0] == 'C') ? 1 : 0] = iTeamScore
  1586.    
  1587.     return PLUGIN_CONTINUE
  1588. }
  1589.  
  1590. public eventIntermission()
  1591. {
  1592.     if (EndPlayer || EndTop15)
  1593.         set_task(1.0, "end_game_stats", 900)
  1594. }
  1595.  
  1596. public end_game_stats()
  1597. {
  1598.     new iaPlayers[32], iPlayer, iPlayers, id
  1599.  
  1600.     if (EndPlayer)
  1601.     {
  1602.         get_players(iaPlayers, iPlayers)
  1603.        
  1604.         for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
  1605.         {
  1606.             id = iaPlayers[iPlayer]
  1607.            
  1608.             if (!g_izStatsSwitch[id])
  1609.                 continue    // Do not show any stats
  1610.            
  1611.             cmdStatsMe(iaPlayers[iPlayer])
  1612.         }
  1613.     }
  1614.     else if (EndTop15)
  1615.     {
  1616.         get_players(iaPlayers, iPlayers)
  1617.         format_top15(g_sBuffer)
  1618.        
  1619.         for (iPlayer = 0; iPlayer < iPlayers; iPlayer++)
  1620.         {
  1621.             id = iaPlayers[iPlayer]
  1622.            
  1623.             if (!g_izStatsSwitch[id])
  1624.                 continue    // Do not show any stats
  1625.            
  1626.             show_motd(iaPlayers[iPlayer], g_sBuffer, "Top 15")
  1627.         }
  1628.     }
  1629.    
  1630.     return PLUGIN_CONTINUE
  1631. }
  1632.  
  1633. public eventSpecMode(id)
  1634. {
  1635.     new sData[12]
  1636.     read_data(2, sData, 11)
  1637.     g_izSpecMode[id] = (sData[10] == '2')
  1638.    
  1639.     return PLUGIN_CONTINUE
  1640. }
  1641.  
  1642. public eventShowRank(id)
  1643. {
  1644.     if (SpecRankInfo && g_izSpecMode[id])
  1645.     {
  1646.         new iPlayer = read_data(2)
  1647.        
  1648.         if (is_user_connected(iPlayer))
  1649.         {
  1650.             new izStats[8], izBody[8]
  1651.             new iRankPos, iRankMax
  1652.            
  1653.             get_user_name(iPlayer, t_sName, MAX_NAME_LENGTH)
  1654.            
  1655.             iRankPos = get_user_stats(iPlayer, izStats, izBody)
  1656.             iRankMax = get_statsnum()
  1657.            
  1658.             set_hudtype_specmode()
  1659.             ShowSyncHudMsg(id, g_HudSync_SpecInfo, "%L", id, "X_RANK_IS", t_sName, iRankPos, iRankMax)
  1660.         }
  1661.     }
  1662.    
  1663.     return PLUGIN_CONTINUE
  1664. }
  1665.  
  1666. public client_connect(id)
  1667. {
  1668.     if (ShowStats)
  1669.     {
  1670.         get_user_info(id, "_amxstatsx", t_sText, MAX_TEXT_LENGTH)
  1671.         g_izStatsSwitch[id] = (t_sText[0]) ? str_to_num(t_sText) : -1
  1672.     }
  1673.     else
  1674.         g_izStatsSwitch[id] = 0
  1675.  
  1676.     g_izKilled[id][KILLED_KILLER_ID] = 0
  1677.     g_izKilled[id][KILLED_KILLER_STATSFIX] = 0
  1678.     g_izShowStatsFlags[id] = 0      // Clear all flags
  1679.     g_fzShowUserStatsTime[id] = 0.0
  1680.  
  1681.     return PLUGIN_CONTINUE
  1682. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top