diff --git a/plugins/ts/menufront.sma b/plugins/ts/menufront.sma new file mode 100755 index 00000000..1ae6e927 --- /dev/null +++ b/plugins/ts/menufront.sma @@ -0,0 +1,201 @@ +/* AMX Mod X +* Menus Front-End Plugin +* +* by the AMX Mod X Development Team +* originally developed by OLO +* +* This file is part of AMX Mod X. +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ + +#include +#include + +new g_menuPosition[33] + +#define MENUS_NUMBER 16 + +new g_menuBody[MENUS_NUMBER][] = { + "KICK_PLAYER", + "BAN_PLAYER", + "SLAP_SLAY", + "TEAM_PLAYER", + + "CHANGEL", + "VOTE_MAPS", + + "SPECH_STUFF", + "CLIENT_COM", + + // Next Page + + "SERVER_COM", + "CVARS_SET", + "CONFIG", + "LANG_SET", + "STATS_SET", + + "PAUSE_PLUG", + "RES_WEAP", + + "TELE_PLAYER" /* Last is Teleport menu - if you want to move it + change also code in displayMenu (look for fun module check) */ +} + +new g_menuCmd[MENUS_NUMBER][] = { + "amx_kickmenu", + "amx_banmenu", + "amx_slapmenu", + "amx_teammenu", + + "amx_mapmenu", + "amx_votemapmenu", + + "amx_speechmenu", + "amx_clcmdmenu", + + // Next Page + + "amx_cmdmenu", + "amx_cvarmenu", + "amx_cfgmenu", + "amx_setlangmenu", + "amx_statscfgmenu", + + "amx_pausecfgmenu", + "amx_restmenu", + + "amx_teleportmenu" +} + +// Second value sets if menu is only for CS... +new g_menuAccess[MENUS_NUMBER][2] = { + {ADMIN_KICK,0}, + {ADMIN_BAN,0}, + {ADMIN_SLAY,0}, + {ADMIN_LEVEL_A,1}, + + {ADMIN_MAP,0}, + {ADMIN_MAP,0}, + + {ADMIN_MENU,0}, + {ADMIN_LEVEL_A,0}, + + // Next Page + + {ADMIN_MENU,0}, + {ADMIN_CVAR,0}, + {ADMIN_MENU,0}, + {ADMIN_CFG,0}, + {ADMIN_CFG,0}, + + {ADMIN_CFG,0}, + {ADMIN_CFG,1}, + + {ADMIN_LEVEL_A,0} +} + +new g_coloredMenus +new g_cstrikeRunning +new g_funModule + +public plugin_init() { + register_plugin("Menus Front-End",AMXX_VERSION_STR,"AMXX Dev Team") + + register_dictionary("menufront.txt") + register_dictionary("common.txt") + + register_menucmd(register_menuid("AMX Mod X Menu"),1023,"actionMenu") + register_clcmd("amxmodmenu","cmdMenu",ADMIN_MENU,"- displays menus") + + g_coloredMenus = colored_menus() + g_cstrikeRunning = cstrike_running() + g_funModule = is_module_loaded("Fun") +} + +public actionMenu(id,key) { + switch (key) { + case 8: displayMenu(id,++g_menuPosition[id]) + case 9: displayMenu(id,--g_menuPosition[id]) + default: client_cmd(id, g_menuCmd[ g_menuPosition[id] * 8 + key ] ) + } + return PLUGIN_HANDLED +} + +displayMenu(id,pos) { + if (pos < 0) return + + new menuBody[512] + new b = 0 + new start = pos * 8 + + if ( start >= MENUS_NUMBER ) + start = pos = g_menuPosition[id] = 0 + + new len = format(menuBody,511, + g_coloredMenus ? "\yAMX Mod X Menu\R%d/%d^n\w^n" : "AMX Mod X Menu %d/%d^n^n" , pos+1, 2 ) + + new end = start + 8 + new keys = MENU_KEY_0 + + if (end > MENUS_NUMBER ) + end = MENUS_NUMBER + + new flags = get_user_flags(id) + + for (new a = start; a < end; ++a) { + if ( a == MENUS_NUMBER - 1 && !g_funModule ) + continue // checks if there is fun module for teleport menu + + if ( (flags & g_menuAccess[a][0]) && ( g_menuAccess[a][1] ? g_cstrikeRunning : 1 ) ) { + keys |= (1< +#include + +#define MAX_MENUPOS 7 // 7 positions in tsstatsmenu +#define StatsTime 5.0 // 5 sec hold time for ShowAttackers , ShowVictims list and ShowKiller + +public EndPlayer // displays player stats at the end of map +public EndTop15 // displays top15 at the end of map + +public SayStatsAll // displays players stats and rank +public SayTop15 // displays first 15. players +public SayRank // displays user position in rank +public SayStatsMe // displays user stats + +public ShowAttackers // shows attackers +public ShowVictims // shows victims +public ShowKiller // shows killer +public KillerHp // displays killer hp to victim console and screen +public SayHP // displays information about user killer +public SayFF // displays friendly fire status + +public GrenadeKill +public GrenadeSuicide +public HeadShotKill +public HeadShotKillSound +public DoubleKill +public DoubleKillSound +public BulletDamage +public TAInfo +public FragInfo + +new g_userPosition[33] +new g_userState[33] +new g_userPlayers[33][32] +new g_Buffer[2048] +new g_Killers[33][3] +new Float:g_DeathStats[33] + +new g_bodyParts[8][] = {"whole body","head","chest","stomach","left arm","right arm","left leg","right leg"} + +new g_HeMessages[4][] = { + "%s sends a little gift to %s", + "%s throws a small present to %s", + "%s made a precision throw to %s", + "%s got a big explosion for %s" +} +new g_SHeMessages[4][] = { + "%s detonated himself with a grenade", + "%s trys the effect of a grenade", + "%s kicked a grenade into his own ass", + "%s explodes!" +} +new g_HeadShots[7][] = { + "$kn killed $vn with a well^nplaced shot to the head!", + "$kn removed $vn's^nhead with the $wn", + "$kn turned $vn's head^ninto pudding with the $wn", + "$vn got pwned by $kn", + "$vn's head has been^nturned into red jello", + "$kn has superb aim with the $wn,^nas $vn well knows.", + "$vn's head stayed in $kn's^ncrosshairs a bit too long..." +} + +public plugin_precache(){ + precache_sound( "misc/headshot.wav") + precache_sound( "misc/doublekill.wav") + return PLUGIN_CONTINUE +} + +new g_disabledMsg[] = "Server has disabled that option" + +public plugin_init() { + register_plugin("TS Stats","0.20ts","SidLuke") + register_event("30","eInterMission","a") + register_event("ResetHUD","eResetHud","b") + register_clcmd("say /hp","cmdKiller",0,"- displays info. about your killer") + register_clcmd("say /stats","cmdStats",0,"- displays others stats") + register_clcmd("say /statsme","cmdStatsMe",0,"- displays your stats") + register_clcmd("say /top15","cmdTop15",0,"- displays top 15 players") + register_clcmd("say /rank","cmdRank",0,"- displays your server stats") + register_clcmd("say /ff","cmdFF",0,"- displays friendly fire status") + register_menucmd(register_menuid("Server Stats"),1023,"actionStatsMenu") + + register_statsfwd(XMF_DAMAGE) + register_statsfwd(XMF_DEATH) +} + + + +public plugin_cfg(){ + new g_addStast[] = "amx_statscfg add ^"%s^" %s" + server_cmd(g_addStast,"Stats at the end of map","EndPlayer") + server_cmd(g_addStast,"Top15 at the end of map","EndTop15") + server_cmd(g_addStast,"Say /stats","SayStatsAll") + server_cmd(g_addStast,"Say /top15","SayTop15") + server_cmd(g_addStast,"Say /rank","SayRank") + server_cmd(g_addStast,"Say /statsme","SayStatsMe") + server_cmd(g_addStast,"Show Attackers","ShowAttackers") + server_cmd(g_addStast,"Show Victims","ShowVictims") + server_cmd(g_addStast,"Show killer","ShowKiller") + server_cmd(g_addStast,"Show killer hp","KillerHp") + server_cmd(g_addStast,"Say /hp","SayHP") + server_cmd(g_addStast,"Say /ff","SayFF") + + server_cmd(g_addStast,"Grenade Kill","GrenadeKill") + server_cmd(g_addStast,"Grenade Suicide","GrenadeSuicide") + server_cmd(g_addStast,"HeadShot Kill","HeadShotKill") + server_cmd(g_addStast,"HeadShot Kill Sound","HeadShotKillSound") + server_cmd(g_addStast,"Double Kill","DoubleKill") + server_cmd(g_addStast,"Double Kill Sound","DoubleKillSound") + server_cmd(g_addStast,"Bullet Damage","BulletDamage") + server_cmd(g_addStast,"TA/TK Info","TAInfo") + server_cmd(g_addStast,"Frag Info","FragInfo") +} + +public cmdFF(id){ + if ( !SayFF ){ + client_print(id,print_chat, g_disabledMsg ) + return PLUGIN_HANDLED + } + client_print( 0, print_chat, "Friendly fire: %s", ( get_cvar_num( "mp_friendlyfire" ) ) ? "ON" : "OFF" ) + return PLUGIN_CONTINUE +} + +public cmdStatsMe(id){ + if ( !SayStatsMe ){ + client_print(id,print_chat, g_disabledMsg ) + return PLUGIN_HANDLED + } + displayStats(id,id) + return PLUGIN_CONTINUE +} + +public displayStats(id,dest) { + new name[32], stats[8], body[8] + get_user_wstats(id,0,stats,body) + new pos = format(g_Buffer,2047,"Kills: %d^nDeaths: %d^nTKs: %d^nDamage: %d^nHits: %d^nShots: %d^n^n", + stats[0],stats[1],stats[3],stats[6],stats[5],stats[4]) + for(new a = 1; a < TSMAX_WEAPONS; ++a) { + if (get_user_wstats(id,a,stats,body)){ + if ( xmod_is_melee_wpn(a) ) + stats[4] = -1; + xmod_get_wpnname(a,name,31) + pos += format(g_Buffer[pos],2047-pos,"%s shots: %d hits: %d damage: %d kills: %d deaths: %d^n", + name,stats[4],stats[5],stats[6],stats[0],stats[1]) + } + } + get_user_name(id,name,31) + show_motd(dest,g_Buffer,name) + return PLUGIN_CONTINUE +} + +public cmdRank(id){ + if ( !SayRank ){ + client_print(id,print_chat, g_disabledMsg ) + return PLUGIN_HANDLED + } + displayRank(id,id) + return PLUGIN_CONTINUE +} + +displayRank(id,dest) { + new name[32], stats[8], body[8] + new rank_pos = get_user_stats(id,stats,body) + new pos = format(g_Buffer,2047,"Kills: %d^nDeaths: %d^nTKs: %d^nDamage: %d^nHits: %d^nShots: %d^n^n", + stats[0],stats[1],stats[3],stats[6],stats[5],stats[4]) + pos += format(g_Buffer[pos],2047-pos,"Hits:^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n%s: %d^n^n", + g_bodyParts[1],body[1],g_bodyParts[2],body[2],g_bodyParts[3],body[3], g_bodyParts[4],body[4], + g_bodyParts[5],body[5],g_bodyParts[6],body[6],g_bodyParts[7],body[7]) + format(g_Buffer[pos],2047-pos,"%s rank is %d of %d",(id==dest)?"Your":"His", rank_pos,get_statsnum()) + get_user_name(id,name,31) + show_motd(dest,g_Buffer,name) +} + +public cmdTop15(id) { + if ( !SayTop15 ){ + client_print(id,print_chat, g_disabledMsg ) + return PLUGIN_HANDLED + } + getTop15() + show_motd(id,g_Buffer,"Top 15") + return PLUGIN_CONTINUE +} + +/* get top 15 */ +getTop15(){ + new stats[8], body[8], name[32] + new pos = copy(g_Buffer,2047,"# nick kills/deaths TKs hits/shots/headshots^n") + new imax = get_statsnum() + if (imax > 15) imax = 15 + for(new a = 0; a < imax; ++a){ + get_stats(a,stats,body,name,31) + pos += format(g_Buffer[pos],2047-pos,"%2d. %-28.27s %d/%d %d %d/%d/%d^n",a+1,name,stats[0],stats[1],stats[3],stats[5],stats[4],stats[2]) + } +} + +public endGameStats(){ + if ( EndPlayer ){ + new players[32], inum + get_players(players,inum) + for(new i = 0; i < inum; ++i) + displayStats(players[i],players[i]) + } + else if ( EndTop15 ) { + new players[32], inum + get_players(players,inum) + getTop15() + for(new i = 0; i < inum; ++i) + show_motd(players[i],g_Buffer,"Top 15") + } +} + +public eInterMission() + set_task(1.0,"endGameStats") + +public cmdStats(id){ + if ( !SayStatsAll ){ + client_print(id,print_chat, g_disabledMsg ) + return PLUGIN_HANDLED + } + showStatsMenu(id,g_userPosition[id]=0) + return PLUGIN_CONTINUE +} + + +/* build list of attackers */ +getAttackers(id) { + new name[32],wpn[32], stats[8],body[8],found=0 + new pos = copy(g_Buffer,2047,"Attackers:^n") + new amax = get_maxplayers() + for(new a = 1; a <= amax; ++a){ + if(get_user_astats(id,a,stats,body,wpn,31)){ + found = 1 + if (stats[0]) + format(wpn,31," -- %s",wpn) + else + wpn[0] = 0 + get_user_name(a,name,31) + pos += format(g_Buffer[pos],2047-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn) + } + } + return found +} + +/* build list of victims */ +getVictims(id) { + new name[32],wpn[32], stats[8],body[8],found=0 + new pos = copy(g_Buffer,2047,"Victims:^n") + new amax = get_maxplayers() + for(new a = 1; a <= amax; ++a){ + if(get_user_vstats(id,a,stats,body,wpn,31)){ + found = 1 + if (stats[1]) + format(wpn,31," -- %s",wpn) + else + wpn[0] = 0 + get_user_name(a,name,31) + pos += format(g_Buffer[pos],2047-pos,"%s -- %d dmg / %d hit(s)%s^n",name,stats[6],stats[5],wpn) + } + } + return found +} + +/* build list of hita for AV List */ +getHits(id,killer) { + new stats[8], body[8], pos = 0 + g_Buffer[0] = 0 + get_user_astats(id,killer,stats,body) + for(new a = 1; a < 8; ++a) + if(body[a]) + pos += format(g_Buffer[pos],2047-pos,"%s: %d^n",g_bodyParts[a],body[a]) +} + + +/* build list of hits for say hp */ +getMyHits(id,killed) { + new name[32], stats[8], body[8], found = 0 + get_user_name(killed,name,31) + new pos = format(g_Buffer,2047,"You hit %s in:",name) + get_user_vstats(id,killed,stats,body) + for(new a = 1; a < 8; ++a){ + if(body[a]){ + found = 1 + pos += format(g_Buffer[pos],2047-pos," %s: %d ",g_bodyParts[a],body[a]) + } + } + return found +} + +public client_damage(attacker,victim,damage,wpnindex,hitplace,TA) { + if ( TA ){ + if ( TAInfo && is_user_alive(victim) ){ + new attacker_name[32] + get_user_name(attacker,attacker_name,31) + client_print(0,print_chat,"%s attacked a teammate",attacker_name) + } + return PLUGIN_CONTINUE + } + if ( BulletDamage ) { + if ( attacker==victim ) return PLUGIN_CONTINUE + set_hudmessage(0, 100, 200, 0.45, 0.85, 2, 0.1, 4.0, 0.02, 0.02, 3) + show_hudmessage(attacker,"%i", damage) + set_hudmessage(200, 0, 0, 0.55, 0.85, 2, 0.1, 4.0, 0.02, 0.02, 4) + show_hudmessage(victim,"%i", damage) + } + return PLUGIN_CONTINUE +} + +public client_death(killer,victim,wpnindex,hitplace,TK){ + new killer_name[32] + get_user_name(killer,killer_name,31) + + if ( TK ){ + if ( TAInfo ){ + client_print(0,print_chat,"%s killed a teammate !",killer_name) + } + return PLUGIN_CONTINUE + } + + new killFlags = ts_getuserkillflags(killer) + new grenade = ( wpnindex == TSW_M61GRENADE ) ? 1:0 + new headshot = ( hitplace == HIT_HEAD ) ? 1:0 + + new victim_name[32] + get_user_name(victim,victim_name,31) + + if ( killer == victim ){ + if ( grenade && GrenadeSuicide ){ + set_hudmessage(255, 100, 100, -1.0, 0.25, 1, 6.0, 6.0, 0.5, 0.15, 1) + show_hudmessage(0,g_SHeMessages[ random_num(0,3) ],victim_name) + } + return PLUGIN_CONTINUE + } + + new vorigin[3], korigin[3] + get_user_origin(victim,vorigin) + get_user_origin(killer,korigin) + g_Killers[victim][0] = killer + g_Killers[victim][1] = get_user_health(killer) + g_Killers[victim][2] = get_distance(vorigin,korigin) + g_DeathStats[victim] = get_gametime() + StatsTime + + if (g_Killers[victim][0]) { + DisplayKillInfo(victim) + DisplayAVList(victim) + DisplayKillerHp(victim,1) + } + + if ( grenade && GrenadeKill ){ + set_hudmessage(255, 100, 100, -1.0, 0.25, 1, 6.0, 6.0, 0.5, 0.15, 1) + for (new i=1;i<=get_maxplayers();i++){ + if ( g_Killers[i][0] && g_DeathStats[i] > get_gametime() ) + continue + show_hudmessage(i,g_HeMessages[ random_num(0,3)],killer_name,victim_name) + } + } + else if ( headshot && (HeadShotKill || HeadShotKillSound) && !xmod_is_melee_wpn(wpnindex) ){ + if ( HeadShotKill ){ + new weapon[32], message[128] + xmod_get_wpnname(wpnindex,weapon,31) + copy( message, 127, g_HeadShots[ random_num(0,6) ] ) + replace( message, 127 , "$vn", victim_name ) + replace( message, 127 , "$wn", weapon ) + replace( message, 127 , "$kn", killer_name ) + set_hudmessage(100, 100, 255, -1.0, 0.29, 0, 6.0, 6.0, 0.5, 0.15, 1) + for (new i=1;i<=get_maxplayers();i++){ + if ( g_Killers[i][0] && g_DeathStats[i] > get_gametime() ) + continue + show_hudmessage(i,message) + } + } + if ( HeadShotKillSound ) client_cmd(0,"spk misc/headshot") + } + + if ( killFlags & TSKF_DOUBLEKILL ){ + if ( DoubleKill ){ + set_hudmessage(65, 102, 158, -1.0, 0.35, 0, 6.0, 6.0, 0.5, 0.15, 3) + for (new i=1;i<=get_maxplayers();i++){ + if ( g_Killers[i][0] && g_DeathStats[i] > get_gametime() ) + continue + show_hudmessage(i,"Wow! %s made a double kill !!!",killer_name) + } + } + if ( DoubleKillSound ) + client_cmd(0,"spk misc/doublekill") + } + + if ( FragInfo ){ + new kmsg[128] + new pos = format(kmsg,63,"LastKill: %d frag(s)^n",ts_getuserlastfrag(killer)) + if ( killFlags ){ + pos += format(kmsg[pos],128-pos,"[") + + if ( killFlags & TSKF_STUNTKILL ) + pos += format(kmsg[pos],128-pos," stunt ") + + if ( killFlags & TSKF_SLIDINGKILL ) + pos += format(kmsg[pos],128-pos," sliding ") + + if ( killFlags & TSKF_DOUBLEKILL ) + pos += format(kmsg[pos],128-pos," double ") + + if ( killFlags & TSKF_ISSPEC ) + pos += format(kmsg[pos],128-pos," spec ") + + if ( killFlags & TSKF_KILLEDSPEC ) + pos += format(kmsg[pos],128-pos," kspec ") + + pos += format(kmsg[pos],128-pos,"]") + } + set_hudmessage(255,255,255,0.02,0.85,2, 1.5, 3.0, 0.02, 5.0, 4) + show_hudmessage(killer,kmsg) + } + + return PLUGIN_CONTINUE +} + +DisplayKillInfo(victim){ + if ( ShowKiller ){ + new name[32], stats[8], body[8], wpn[33], mstats[8], mbody[8] + get_user_name(g_Killers[victim][0],name,31) + get_user_astats(victim,g_Killers[victim][0],stats,body,wpn,31) + get_user_vstats(victim,g_Killers[victim][0],mstats,mbody) + set_hudmessage(220,80,0,0.05,0.15,0, 6.0, 12.0, 1.0, 2.0, 1) + getHits(victim,g_Killers[victim][0]) + show_hudmessage(victim,"%s killed you with %s^nfrom distance of %.2f meters.^nHe did %d damage to you with %d hit(s)^nand still has %dhp.^nYou did %d damage to him with %d hit(s).^nHe hits you in:^n%s", + name,wpn,float(g_Killers[victim][2]) * 0.0254, stats[6],stats[5], + g_Killers[victim][1], mstats[6],mstats[5],g_Buffer ) + } +} + +DisplayAVList(victim){ + if ( ShowVictims && getVictims(victim) ){ + set_hudmessage(0,80,220,0.55,0.60,0, 6.0, 12.0, 1.0, 2.0, 4) + show_hudmessage(victim,g_Buffer) + } + if ( ShowAttackers && getAttackers(victim)){ + set_hudmessage(220,80,0,0.55,0.35,0, 6.0, 12.0, 1.0, 2.0, 3) + show_hudmessage(victim,g_Buffer) + } +} + +DisplayKillerHp(victim,con){ + if ( KillerHp ){ + new name[32], kmsg[128] + get_user_name(g_Killers[victim][0],name,31) + format(kmsg,127,"%s still has %dhp",name,g_Killers[victim][1]) + if ( con ) client_print(victim,print_console,kmsg) + set_hudmessage(255,255,255,0.02,0.9,2, 1.5, 3.0, 0.02, 5.0, 2) + show_hudmessage(victim,kmsg) + } +} + +public eResetHud( id ){ + if ( !is_user_alive(id) ){ + if ( id != g_Killers[id][0] && g_Killers[id][0] ){ + DisplayKillInfo(id) + DisplayAVList(id) + DisplayKillerHp(id,0) + } + } + else { + g_Killers[ id ][0] = 0 + } +} + +public cmdKiller(id) { + if ( !SayHP ){ + client_print(id,print_chat, g_disabledMsg ) + return PLUGIN_HANDLED + } + if (g_Killers[id][0]) { + new name[32], stats[8], body[8], wpn[33], mstats[8], mbody[8] + get_user_name(g_Killers[id][0],name,31) + get_user_astats(id,g_Killers[id][0],stats,body,wpn,31) + get_user_vstats(id,g_Killers[id][0],mstats,mbody) + client_print(id,print_chat,"%s killed you with %s from distance of %.2f meters", name,wpn,float(g_Killers[id][2]) * 0.0254 ) + client_print(id,print_chat,"He did %d damage to you with %d hit(s) and still had %dhp", + stats[6],stats[5], g_Killers[id][1] ) + client_print(id,print_chat,"You did %d damage to him with %d hit(s)",mstats[6], mstats[5] ) + if (getMyHits(id,g_Killers[id][0])) client_print(id,print_chat,g_Buffer) + } + else { + client_print(id,print_chat,"You have no killer...") + } + return PLUGIN_CONTINUE +} + +public actionStatsMenu(id,key){ + switch(key){ + case 7: { + g_userState[id] = 1 - g_userState[id] + showStatsMenu(id,g_userPosition[id]) + } + case 8: showStatsMenu(id,++g_userPosition[id]) + case 9: showStatsMenu(id,--g_userPosition[id]) + default:{ + new option = g_userPosition[id] * MAX_MENUPOS + key + new index = g_userPlayers[id][option] + if (is_user_connected(index)){ + if (g_userState[id]) + displayRank(index,id) + else + displayStats(index,id) + } + showStatsMenu(id,g_userPosition[id]) + } + } + return PLUGIN_HANDLED +} + +showStatsMenu(id,pos){ + if (pos < 0) return PLUGIN_HANDLED + new menu_body[512], inum, k = 0, start = pos * MAX_MENUPOS + get_players(g_userPlayers[id],inum) + if (start >= inum) start = pos = g_userPosition[id] = 0 + new len = format(menu_body,511,"Server Stats %d/%d^n^n",pos + 1,((inum/MAX_MENUPOS)+((inum%MAX_MENUPOS)?1:0))) + new name[32], end = start + MAX_MENUPOS, keys = (1<<9)|(1<<7) + if (end > inum) end = inum + for(new a = start; a < end; ++a){ + get_user_name(g_userPlayers[id][a],name,31) + keys |= (1< +#include + +new g_pingSum[33] +new g_pingCount[33] + +public plugin_init() + register_plugin("Stats Logging","0.20ts","SidLuke") + +public client_disconnect(id) { + if ( is_user_bot( id ) ) return PLUGIN_CONTINUE + remove_task( id ) + new szTeam[16],szName[32],szAuthid[32], iStats[8], iHits[8], szWeapon[16] + new iUserid = get_user_userid( id ) + + // team + get_user_info(id,"team", szTeam, 15 ) + + get_user_name(id, szName ,31 ) + get_user_authid(id, szAuthid , 31 ) + for(new i = 1 ; i < TSMAX_WEAPONS ; ++i ) { + if( get_user_wstats( id , i ,iStats , iHits ) ) { + xmod_get_wpnlogname( i , szWeapon , 15 ) + log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"%s^") (shots ^"%d^") (hits ^"%d^") (kills ^"%d^") (headshots ^"%d^") (tks ^"%d^") (damage ^"%d^") (deaths ^"%d^")", + szName,iUserid,szAuthid,szTeam,szWeapon,iStats[4],iStats[5],iStats[0], + iStats[2],iStats[3],iStats[6],iStats[1]) + + log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"%s^") (head ^"%d^") (chest ^"%d^") (stomach ^"%d^") (leftarm ^"%d^") (rightarm ^"%d^") (leftleg ^"%d^") (rightleg ^"%d^")", + szName,iUserid,szAuthid,szTeam,szWeapon,iHits[1],iHits[2],iHits[3], + iHits[4],iHits[5],iHits[6],iHits[7]) + } + } + new iTime = get_user_time( id , 1 ) + log_message("^"%s<%d><%s><%s>^" triggered ^"time^" (time ^"%d:%02d^")", + szName,iUserid,szAuthid,szTeam, (iTime / 60), (iTime % 60) ) + log_message("^"%s<%d><%s><%s>^" triggered ^"latency^" (ping ^"%d^")", + szName,iUserid,szAuthid,szTeam, (g_pingSum[id] / ( g_pingCount[id] ? g_pingCount[id] : 1 ) ) ) + return PLUGIN_CONTINUE +} + +public client_putinserver(id) { + if ( !is_user_bot( id ) ){ + g_pingSum[ id ] = g_pingCount[ id ] = 0 + set_task( 19.5 , "getPing" , id , "" , 0 , "b" ) + } +} + +public getPing( id ) { + new iPing, iLoss + get_user_ping( id , iPing, iLoss) + g_pingSum[ id ] += iPing + ++g_pingCount[ id ] +} + +public plugin_modules() +{ + require_module("tsx") +} diff --git a/plugins/ts/statscfg.sma b/plugins/ts/statscfg.sma new file mode 100755 index 00000000..8085f4aa --- /dev/null +++ b/plugins/ts/statscfg.sma @@ -0,0 +1,240 @@ +/* AMX Mod X +* Stats Configuration Plugin +* +* by the AMX Mod X Development Team +* originally developed by OLO +* +* This file is part of AMX Mod X. +* +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game Engine ("HL +* Engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL Engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +*/ + +#include +#include + +#define MAX_MENU_DATA 64 + +new g_menuData[MAX_MENU_DATA][32] +new g_menuDataVar[MAX_MENU_DATA][32] +new g_menuDataId[MAX_MENU_DATA] +new g_menuDataNum +new g_menuPosition[33] +new g_fileToSave[64] +new bool:g_modified + +public plugin_precache() { + register_clcmd("amx_statscfgmenu","cmdCfgMenu",ADMIN_CFG,"- displays stats configuration menu") + register_dictionary("statscfg.txt") + register_dictionary("common.txt") + register_concmd("amx_statscfg","cmdCfg",ADMIN_CFG,"- displays help for stats configuration") +} + +public plugin_init() { + register_plugin("Stats Configuration",AMXX_VERSION_STR,"AMXX Dev Team") + register_menucmd(register_menuid("Stats Configuration"),1023,"actionCfgMenu") + get_configsdir(g_fileToSave, 63) + format(g_fileToSave, 63, "%s/stats.ini", g_fileToSave) + loadSettings(g_fileToSave) +} + +public cmdCfg( id,level,cid ) { + if (!cmd_access(id,level,cid,1)) + return PLUGIN_HANDLED + + new cmds[32] + read_argv(1,cmds,31) + new option = equali(cmds, "on" ) ? 1 : 0 + if ( !option ) option = equali(cmds, "off" ) ? 2 : 0 + if ( read_argc() > 2 && option ) { + new var[32], enabled = 0 + read_argv( 2 , var , 31 ) + for ( new a = 0; a < g_menuDataNum; ++a ) { + if ( containi( g_menuDataVar[ a ] , var ) != -1 ) { + g_modified = true + ++enabled + if ( option == 1 ) { + set_xvar_num( g_menuDataId[a] , 1 ) + console_print(id,"Enabled %s" , g_menuData[a] ) + } + else { + set_xvar_num( g_menuDataId[a] , 0 ) + console_print(id,"Disabled %s" , g_menuData[a] ) + } + } + } + if ( enabled ) + console_print(id,"%L", id, "TOTAL_NUM", enabled ) + else + console_print(id,"%L",id,"NO_OPTION",var ) + } + else if ( equali(cmds, "save" ) ) { + if ( saveSettings( g_fileToSave ) ){ + g_modified = false + console_print(id,"%L",id,"CONF_SAVED") + } + else + console_print(id,"%L",id,"CONF_FAILED") + } + else if ( equali(cmds, "load" ) ) { + if ( loadSettings( g_fileToSave ) ){ + g_modified = false + console_print(id,"%L",id,"CONF_LOADED") + } + else + console_print(id,"%L",id,"CONF_FAIL_LOAD") + } + else if ( equali(cmds, "list" ) ) { + new arg1[8] + new start = read_argv(2,arg1,7) ? str_to_num(arg1) : 1 + if (--start < 0) start = 0 + if (start >= g_menuDataNum) start = g_menuDataNum - 1 + new end = start + 10 + if (end > g_menuDataNum) end = g_menuDataNum + + new lName[16],lVariable[16],lStatus[16] + format(lName,15,"%L",id,"NAME") + format(lVariable,15,"%L",id,"VARIABLE") + format(lStatus,15,"%L",id,"STATUS") + console_print(id, "^n----- %L: -----",id,"STATS_CONF") + console_print(id, " %-29.28s %-24.23s %-9.8s",lName,lVariable,lStatus) + if ( start != -1 ) { + new lOnOff[16] + for (new a = start; a < end; ++a) { + format(lOnOff,15,"%L",id,get_xvar_num( g_menuDataId[ a ] ) ? "ON" : "OFF") + console_print(id, "%3d: %-29.28s %-24.23s %-9.8s",a + 1, + g_menuData[a], g_menuDataVar[a], lOnOff) + } + } + console_print(id,"----- %L -----",id,"ENTRIES_OF",start+1,end,g_menuDataNum) + if (end < g_menuDataNum) + console_print(id,"----- %L -----",id,"USE_MORE",end+1) + else + console_print(id,"----- %L -----",id,"USE_BEGIN") + } + else if ( equali(cmds, "add" ) && read_argc() > 3 ) { + if ( g_menuDataNum < MAX_MENU_DATA ) { + read_argv(2, g_menuData[g_menuDataNum] , 31 ) + read_argv(3, g_menuDataVar[g_menuDataNum] , 31 ) + g_menuDataId[g_menuDataNum] = get_xvar_id( g_menuDataVar[g_menuDataNum] ) + ++g_menuDataNum + } + else console_print(id, "%L",id,"CANT_ADD") + } + else { + console_print(id,"%L",id,"COM_USAGE") + console_print(id,"%L",id,"COM_COM") + console_print(id,"%L",id,"COM_ON") + console_print(id,"%L",id,"COM_OFF") + console_print(id,"%L",id,"COM_SAVE") + console_print(id,"%L",id,"COM_LOAD") + console_print(id,"%L",id,"COM_LIST") + console_print(id,"%L",id,"COM_ADD") + } + + return PLUGIN_HANDLED +} + +public cmdCfgMenu(id,level,cid) { + if (cmd_access(id,level,cid,1)) + displayCfgMenu(id,g_menuPosition[id] = 0) + return PLUGIN_HANDLED +} + +displayCfgMenu(id,pos) { + if (pos < 0) return + new menu_body[512], start = pos * 7 + if (start >= g_menuDataNum) start = pos = g_menuPosition[id] = 0 + new len = format(menu_body,511,"%L %d/%d^n^n", + id,"STATS_CONF",pos + 1,((g_menuDataNum/7)+((g_menuDataNum%7)?1:0))) + new end = start + 7, keys = MENU_KEY_0|MENU_KEY_8, k = 0 + if (end > g_menuDataNum) end = g_menuDataNum + for (new a = start; a < end; ++a) { + keys |= (1< + +public plugin_precache(){ + precache_sound( "misc/impressive.wav") + precache_sound( "misc/headshot.wav") + precache_sound( "misc/multikill.wav") + precache_sound( "misc/doublekill.wav") + precache_sound( "misc/godlike.wav") + precache_sound( "misc/ultrakill.wav") + precache_sound( "misc/killingspree.wav") + precache_sound( "misc/rampage.wav") + precache_sound( "misc/unstoppable.wav") + precache_sound( "misc/monsterkill.wav") + precache_sound( "misc/humiliation.wav") + + precache_sound( "misc/takenlead.wav" ) + precache_sound( "misc/tiedlead.wav" ) + precache_sound( "misc/lostlead.wav" ) + + return PLUGIN_CONTINUE +} + +public plugin_init() { + register_plugin("TFC Sounds Precache","0.20ts","SidLuke") +} \ No newline at end of file diff --git a/plugins/ts/tsstats.sma b/plugins/ts/tsstats.sma new file mode 100755 index 00000000..73a70551 --- /dev/null +++ b/plugins/ts/tsstats.sma @@ -0,0 +1,25 @@ +/* Get Score for TS STATS. + * + * (c) 2004, SidLuke + * This file is provided as is (no warranties). + * + * Function calculates position in rank. + * + * Stats: + * 0 - kills + * 1 - deaths + * 2 - headshots + * 3 - teamkilling + * 4 - shots + * 5 - hits + * 6 - damage + * + * File location: $moddir/addons/amxx + */ + +#include + +public get_score(stats[8],body[8]) +{ + return stats[0] - stats[1] - stats[3] /* kills - deaths - TKs */ +} \ No newline at end of file