Raised This Month: $51 Target: $400
 12% 

Subplugin Submission [ZP43Fix5a|ZP50] Addon: Stats, ExpMod & Ranking System.


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
yokomo
Surprise Ascot!
Join Date: May 2010
Location: Malaysia
Old 03-31-2015 , 14:12   [ZP43Fix5a|ZP50] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #1

This plugin save data using nvault module if you want sqlite then ask someone else to code it for you, i have zero knowledge on sqlite.

Descriptions:
This is a basic stats and EXP mod for Zombie Plague, so people can earn EXP and level up to next rank. This plugin more like an API so you need to create your own sub-plugin to add awards, player ability, free item and so on.

Modules & Includes:
Engine
Hamsandwich
Nvault
GeoIP
nVault Utility

Natives & Forwards:
Spoiler


Player Chat Commands:
/stats -- Open player stats menu.
/rank -- Show your current rank.
/top15 , /top10 , /globaltop -- Show global Top-10 players.
/onlinetop -- Show online Top-10 players.

ZP Version:
- ZP4.3Fix5a
- ZP5.0

Customizations:
Open .sma file and change what you want.

Screenshots:
Default motd.txt

Player HUD

Spectator HUD

Player Rank

Global Top 10

Online Top 10

Player Stats Menu

Player Stats


Issues:
- Some feature may not work correctly when server first run. To solve this just join your server and change map.
- Player data only save once when they disconnect from server. To update player data, they need to rejoin the server

Credits:
Exolent[jNr] -- Sort Top15 tutorial using nvault_util.
Bugsy -- Time stock, nVault Utility.
Destro -- MOTD layout.
Excalibur.007 -- Rank names and exp points.
[ --<-@ ] Black Rose -- String to Int stock.

Changes Log:
Spoiler


Plugins base on this API:
- [ZP50] Addon: Level Upgrades -- https://forums.alliedmods.net/showthread.php?t=261564
- [ZP43] Class: Custom Zombie Classes -- https://forums.alliedmods.net/showpo...8&postcount=21
- [ZP50] Class: Custom Zombie Classes -- https://forums.alliedmods.net/showpo...7&postcount=22
- [ZP43] Item: Damage Multiplier For One Round -- https://forums.alliedmods.net/showpo...3&postcount=36

If you want to save data by user name then use zp_exp_stats_name_reg.sma version, it has build-in registration system.
Attached Files
File Type: sma Get Plugin or Get Source (zp_exp_stats.sma - 1760 views - 30.0 KB)
File Type: inc zpexpmod.inc (2.2 KB, 824 views)
__________________
Team-MMG CS1.6 Servers:
✅ MultiMod -- 103.179.44.152:27016
✅ Zombie Plague -- 103.179.44.152:27015
✅ Zombie Escape -- 103.179.44.152:27017
✅ Klassik Kombat -- 103.179.44.152:27018
✅ Boss-Battle -- 103.179.44.152:27019

Last edited by yokomo; 04-28-2015 at 00:15. Reason: Update to version 0.0.4
yokomo is offline
yokomo
Surprise Ascot!
Join Date: May 2010
Location: Malaysia
Old 03-31-2015 , 15:01   Re: [ZP43Fix5a] Addon: Simple Stats & ExpMod.
Reply With Quote #2

Example sub-plugins that use xp_* API.

zp_test_xp_api.sma -- this will show you how to give awards to player.
zp_zclass_level3.sma -- this will show you how to create level base zombie class.
Attached Files
File Type: sma Get Plugin or Get Source (zp_test_xp_api.sma - 1445 views - 2.7 KB)
File Type: sma Get Plugin or Get Source (zp_zclass_level3.sma - 1222 views - 1.4 KB)
__________________
Team-MMG CS1.6 Servers:
✅ MultiMod -- 103.179.44.152:27016
✅ Zombie Plague -- 103.179.44.152:27015
✅ Zombie Escape -- 103.179.44.152:27017
✅ Klassik Kombat -- 103.179.44.152:27018
✅ Boss-Battle -- 103.179.44.152:27019

Last edited by yokomo; 03-31-2015 at 15:01.
yokomo is offline
Old 03-31-2015, 15:16
New.ZM.Life
This message has been deleted by New.ZM.Life. Reason: sry---losts oof mistakes xD
New.ZM.Life
Veteran Member
Join Date: Sep 2014
Location: Iran
Old 03-31-2015 , 15:37   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #3

not availabe for AMX MOD X 1.8.2 ?
__________________
PLUGINS

Zombie Plague 5.0 + New Modes

Added NightCrawler Mode to ZP





New.ZM.Life is offline
yokomo
Surprise Ascot!
Join Date: May 2010
Location: Malaysia
Old 03-31-2015 , 16:01   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #4

Quote:
Originally Posted by New.ZM.Life View Post
not availabe for AMX MOD X 1.8.2 ?
Sorry, only for amxmodx 1.8.3dev. We need to use 1.8.3dev anyway, soon this version will become public too. Not sure how long it take to test, because lack of user to use dev build.
__________________
Team-MMG CS1.6 Servers:
✅ MultiMod -- 103.179.44.152:27016
✅ Zombie Plague -- 103.179.44.152:27015
✅ Zombie Escape -- 103.179.44.152:27017
✅ Klassik Kombat -- 103.179.44.152:27018
✅ Boss-Battle -- 103.179.44.152:27019
yokomo is offline
wicho
Veteran Member
Join Date: Feb 2012
Location: GuateAmala
Old 03-31-2015 , 16:59   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #5

to 5.0 but not tested..

PHP Code:
#include <amxmodx>
#include <engine>
#include <hamsandwich>
#include <nvault_util>
#include <geoip>
#include <zp50_core> 
#include <zp50_class_nemesis> 
#include <zp50_class_survivor> 
#include <zp50_ammopacks> 

new const szRanks[][] = 
{
    
"Private (0)"// 0
    
"Private 1st Class (1)"// 1
    
"Corporal (2)"// 2
    
"Sergeant (3)"// 3
    
"Staff Sergeant (4)"// 4
    
"Sergeant 1st Class (5)"// 5
    
"Master Sergeant (6)"// 6
    
"Sergeant Major (7)"// 7
    
"2nd Lieutenant (8)"// 8
    
"1st Lieutenant (9)"// 9
    
"Captain (10)"// 10
    
"Major (11)"// 11
    
"Lieutenant Colonel (12)"// 12
    
"Colonel (13)"// 13
    
"Brigadier General (14)"// 14
    
"Major General (15)"// 15
    
"Lieutenant General (16)"// 16
    
"General (17)"// 17
    
"General of the Army (18)"// 18
    
"Otai (19)" //19 max level only cheater may achieve this rank
}

new const 
iEXP[] = 
{
    
0// 0
    
50// 1
    
100// 2
    
200// 3
    
400// 4
    
800// 5
    
1600// 6
    
3200// 7
    
6400// 8
    
12800// 9
    
25600// 10
    
51200// 11
    
102400// 12
    
204800// 13
    
409600// 14
    
819200// 15
    
1638400// 16
    
3276800// 17
    
6553600// 18
    
9999999 //19 max level only cheater may achieve this rank
}

enum _:Player_Data
{
    
Data_Steamid[35],
    
Data_Name[32],
    
Data_Exp,
    
Data_Kills,
    
Data_Deaths,
    
Data_HeadShot,
    
Data_Knife,
    
Data_Nade,
    
Data_NemKills,
    
Data_SurKills,
    
Data_PlayTime,
    
Data_Level,
    
Data_Country[46],
    
Data_Rank,
    
MAX_PLAYER_DATA
}

enum _:Forward_Data
{
    
Forward_Login,
    
Forward_Levelup,
    
Forward_Result,
    
MAX_FORWARD_DATA
}

#define flag_get(%1,%2) (%1 & (1 << (%2 & 31)))
#define flag_set(%1,%2) %1 |= (1 << (%2 & 31))
#define flag_unset(%1,%2) %1 &= ~(1 << (%2 & 31))

new g_IsConnected

new iVaultHandlegData[33][MAX_PLAYER_DATA], bool:bIsLoaded[33], iHudStatsFloat:fLastHud[33], szMotd[1536], gForward[MAX_FORWARD_DATA], Float:fLastCmdiTotalEntries
const iExpKill 3
const iExpHeadShot 3
const iExpKnife 5
const iExpGrenade 8
const iExpNemKill 20
const iExpSurKill 15
const Float:HUD_STATS_X = -1.0
const Float:HUD_STATS_Y 0.8
new const szVaultName[] = "zpexpmod"
#define PLUGIN_VERSION "0.0.1"
#define CVAR_EXP_VERSION "zp_simple_stats"

//Uncomment this to update motd.txt on map loaded to show global top-10 players.
//#define UPDATE_MOTD

//Uncomment this to enable nvault prune.
#define PRUNE_DATABASE

#if defined UPDATE_MOTD
new const szFileMotd[] = "motd.txt"
#endif

#if defined PRUNE_DATABASE
const iExpiredDays 15
#endif

public plugin_natives()
{
    
register_native("xp_get_user_exp","_get_user_exp",1)
    
register_native("xp_set_user_exp","_set_user_exp",1)
    
    
register_native("xp_get_user_playtime","_get_user_playtime",1)
    
register_native("xp_set_user_playtime","_set_user_playtime",1)
    
    
register_native("xp_get_user_level","_get_user_level",1)
    
register_native("xp_set_user_level","_set_user_level",1)
    
    
register_native("xp_get_user_deaths","_get_user_deaths",1)
    
register_native("xp_set_user_deaths","_set_user_deaths",1)
    
    
register_native("xp_get_user_frags","_get_user_frags",1)
    
register_native("xp_set_user_frags","_set_user_frags",1)
    
    
register_native("xp_get_user_headshot","_get_user_headshot",1)
    
register_native("xp_set_user_headshot","_set_user_headshot",1)
    
    
register_native("xp_get_user_knife","_get_user_knife",1)
    
register_native("xp_set_user_knife","_set_user_knife",1)
    
    
register_native("xp_get_user_nade","_get_user_nade",1)
    
register_native("xp_set_user_nade","_set_user_nade",1)
    
    
register_native("xp_get_user_nemesis","_get_user_nemesis",1)
    
register_native("xp_set_user_nemesis","_set_user_nemesis",1)
    
    
register_native("xp_get_user_survivor","_get_user_survivor",1)
    
register_native("xp_set_user_survivor","_set_user_survivor",1)
    
    
register_native("xp_reset_user_data","_reset_user_data",1)
    
register_native("xp_get_user_rank","_get_user_rank",1)
}

public 
plugin_init()
{
    
register_plugin("ZP Simple Stats"PLUGIN_VERSION"wbyokomo")
    
    
register_event("DeathMsg""OnDeathMsg""a"//use deathmsg easy to trace weapon and hitplace
    
    
iHudStats CreateHudSyncObj()
    
RegisterHam(Ham_Player_PreThink"player""OnPlayerPreThink"//no need for csbot
    
    
register_clcmd("say /stats" "CmdStats")
    
register_clcmd("say /rank""CmdShowRank")
    
register_clcmd("say /top15""CmdTopExpGlobal")
    
register_clcmd("say /top10""CmdTopExpGlobal")
    
register_clcmd("say /globaltop""CmdTopExpGlobal")
    
register_clcmd("say /onlinetop""CmdTopExpOnline")
    
    
register_clcmd("say_team /stats" "CmdStats")
    
register_clcmd("say_team /rank""CmdShowRank")
    
register_clcmd("say_team /top15""CmdTopExpGlobal")
    
register_clcmd("say_team /top10""CmdTopExpGlobal")
    
register_clcmd("say_team /globaltop""CmdTopExpGlobal")
    
register_clcmd("say_team /onlinetop""CmdTopExpOnline")
    
    
gForward[Forward_Login] = CreateMultiForward("xp_user_login"ET_IGNOREFP_CELLFP_CELLFP_CELL//xp_user_login(player, level, exp)
    
gForward[Forward_Levelup] = CreateMultiForward("xp_user_levelup"ET_IGNOREFP_CELLFP_CELLFP_CELL//xp_user_levelup(player, level, exp)
    
    
register_cvar(CVAR_EXP_VERSIONPLUGIN_VERSIONFCVAR_SERVER|FCVAR_SPONLY)
    
set_cvar_string(CVAR_EXP_VERSIONPLUGIN_VERSION)
}

public 
plugin_cfg()
{
    
iVaultHandle nvault_open(szVaultName)
    
    if(
iVaultHandle == INVALID_HANDLE)
    {
        
set_fail_state("Error opening nVault file [%s]"szVaultName)
    }
    else
    {
        
server_print("Database [%s] successfully loaded..."szVaultName)
        
        
#if defined PRUNE_DATABASE
        
nvault_prune(iVaultHandle0get_systime() - (86400 iExpiredDays))
        
#endif
        
        
FormatGlobalTopTen()
        
        
#if defined UPDATE_MOTD
        
if(file_exists(szFileMotd))
        {
            if(
delete_file(szFileMotd))
            {
                if(
write_file(szFileMotdszMotd, -1)) server_print("File [%s] has been updated..."szFileMotd);
            }
        }
        
#endif
    
}
    
    
set_task(0.6"TurnOfDefHud")
}

public 
TurnOfDefHud()
{
    if(
cvar_exists("zp_hud_display")) set_cvar_num("zp_hud_display"0);
    else 
set_fail_state("This plugin compatible only with ZP4.3Fix5a. Download 'zp_plugin_43_patched.zip' at http://forums.alliedmods.net/showthread.php?t=72505");
}

public 
plugin_end()
{
    
nvault_close(iVaultHandle)
}

public 
client_putinserver(id)
{
    
get_user_authid(idgData[id][Data_Steamid], 34)
    
LoadPlayerData(id)
    
get_user_name(idgData[id][Data_Name], 31)
    new 
szIp[32]; get_user_ip(idszIp311);
    
geoip_country_ex(szIpgData[id][Data_Country], 45)
    if(
equali(gData[id][Data_Country],"")) copy(gData[id][Data_Country], 45"Unknown");
    
gData[id][Data_Rank] = -1
    flag_set
(g_IsConnectedid)
}

public 
client_disconnect(id)
{
    if(
bIsLoaded[id])
    {
        
gData[id][Data_PlayTime] += get_user_time(id)
        
SavePlayerData(id)
    }
    else
    {
        
log_to_file("exp_log.log""Player: %s | Steamid: %s -- failed to save data."gData[id][Data_Name], gData[id][Data_Steamid])
    }
    
    
flag_unset(g_IsConnectedid)
}

public 
client_infochanged(id)
{
    if(
flag_get(g_IsConnectedidget_user_info(id"name"gData[id][Data_Name], 31));
}

public 
CmdStats(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    new 
menu menu_create("\yPlayer Stats:""PlayerStatsMenuHandler")
    new 
szUserId[32], id2
    
for(id2=1;id2<=MaxClients;id2++)
    {
        if(!
flag_get(g_IsConnectedid2)) continue;
        
        
formatex(szUserIdcharsmax(szUserId), "%d"get_user_userid(id2))
        
menu_additem(menugData[id2][Data_Name], szUserId0)
    }
    
    
menu_display(idmenu0)
    
    return 
PLUGIN_HANDLED;
}

public 
PlayerStatsMenuHandler(idmenuitem)
{
    if(!
flag_get(g_IsConnectedid))
    {
        
menu_destroy(menu)
        return 
PLUGIN_HANDLED;
    }
    
    if(
item == MENU_EXIT)
    {
        
menu_destroy(menu)
        return 
PLUGIN_HANDLED;
    }
    
    new 
szData[6], szName[64]
    new 
_accessitem_callback
    menu_item_getinfo
(menuitem_accessszData,charsmax(szData), szName,charsmax(szName), item_callback)
    
    new 
userid str_to_num(szData)
    new 
player find_player("k"userid)
    
    if(
player && flag_get(g_IsConnectedplayer))
    {
        
GetPlayerStats(playerid)
    }
    
    
menu_destroy(menu)
    return 
PLUGIN_HANDLED;
}

public 
CmdShowRank(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    static 
Float:ctimectime get_gametime();
    if(
fLastCmd ctime)
    {
        
client_print(idprint_chat"System is busy please wait for %.1f second(s)."fLastCmd-ctime)
        return 
PLUGIN_HANDLED;
    }
    
    
fLastCmd ctime+2.0
    
new iRank SortPlayerRank(id)
    if(
iRank == -1client_print(idprint_chat"Your rank is not been saved yet, please rejoin the server.");
    else 
client_print_color(0print_team_default"^4%s^1 rank is^4 %d^1/^4%d^1 -- Kills:^4 %d^1 Deaths:^4 %d^1 Level:^4 %d^1 EXP:^4 %d^1/^4%d"gData[id][Data_Name], iRankiTotalEntriesgData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_Level], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1])
    
    return 
PLUGIN_HANDLED;
}

public 
CmdTopExpGlobal(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    static 
Float:ctimectime get_gametime();
    if(
fLastCmd ctime)
    {
        
client_print(idprint_chat"System is busy please wait for %.1f second(s)."fLastCmd-ctime)
        return 
PLUGIN_HANDLED;
    }
    
    
fLastCmd ctime+2.0
    show_motd
(idszMotd"TOP-10 Players (GLOBAL)")
    
    return 
PLUGIN_HANDLED;
}

public 
CmdTopExpOnline(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    static 
Float:ctimectime get_gametime();
    if(
fLastCmd ctime)
    {
        
client_print(idprint_chat"System is busy please wait for %.1f second(s)."fLastCmd-ctime)
        return 
PLUGIN_HANDLED;
    }
    
    
fLastCmd ctime+2.0
    
static Sort[33][2]
    new 
players[32], numcountindex
    get_players
(playersnum)
    
    for(new 
0numi++)
    {
        
index players[i]
        
Sort[count][0] = index
        Sort
[count][1] = gData[index][Data_Exp]
        
count++
    }
    
    
SortCustom2D(Sortcount"CompareEXP")
    
    new 
clamp(count010)
    new 
kindexszMotd2[1536], len
    szMotd2
[0] = 0
    
    add
(szMotd2charsmax(szMotd2),
    
"<html><style>\
    body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
    .t{color:#808080;text-align:left; }\
    #h{background: #0066CC url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
    #p{color:#D41313;}\
    #n{color:#fff;}\
    </style><body>\
    <table cellspacing=0 width=100% class=t>"
)
    
    
add(szMotd2charsmax(szMotd2),
    
"<tr><td id=h width=7%>#</td>\
    <td id=h>Name</td>\
    <td id=h>EXP</td>\
    <td id=h>Kills</td>\
    <td id=h>Deaths</td>\
    <td id=h>Online</td></tr>"
)
    
    
len strlen(szMotd2)
    
    for(new 
0yx++)
    {
        
kindex Sort[x][0]
        new 
iSecszTimeFormat[32]
        
iSec get_user_time(kindex)+gData[kindex][Data_PlayTime]
        
GetTimeFormat(iSecszTimeFormat31)
        
        
replace_all(gData[kindex][Data_Name], 31"<""&lt")
        
replace_all(gData[kindex][Data_Name], 31">""&gt")
        
        
len += formatex(szMotd2[len], charsmax(szMotd2)-len,
        
"<tr><td id=p>%d</td>\
        <td id=n>%s</td>\
        <td>%d</td>\
        <td>%d</td>\
        <td>%d</td>\
        <td>%s</td>"
, (x+1), gData[kindex][Data_Name], gData[kindex][Data_Exp], gData[kindex][Data_Kills], gData[kindex][Data_Deaths], szTimeFormat)
    }
    
    
add(szMotd2charsmax(szMotd2), "</table></body></html>")
    
show_motd(idszMotd2"TOP-10 Players (ONLINE)")
    
    return 
PLUGIN_HANDLED;
}

public 
CompareEXP(elem1[], elem2[])
{
    if(
elem1[1] > elem2[1]) return -1;
    else if(
elem1[1] < elem2[1]) return 1;
    
    return 
0;
}

public 
OnDeathMsg()
{
    new 
atkvichsszWpn[4]
    
atk read_data(1)
    
vic read_data(2)
    
hs read_data(3)
    
read_data(4szWpn3)
    
    if(
flag_get(g_IsConnectedvic))
    {
        
gData[vic][Data_Deaths]++
    }
    
    if((
atk != vic) && flag_get(g_IsConnectedatk))
    {
        
gData[atk][Data_Kills]++
        
gData[atk][Data_Exp] += iExpKill
        
        
if(hs)
        {
            
gData[atk][Data_HeadShot]++
            
gData[atk][Data_Exp] += iExpHeadShot
        
}
        
        if(
zp_class_nemesis_get(vic))
        {
            
gData[atk][Data_NemKills]++
            
gData[atk][Data_Exp] += iExpNemKill
        
}
        else if(
zp_class_survivor_get(vic))
        {
            
gData[atk][Data_SurKills]++
            
gData[atk][Data_Exp] += iExpSurKill
        
}
        
        if(
szWpn[0]=='k' && szWpn[1]=='n')
        {
            
gData[atk][Data_Knife]++
            
gData[atk][Data_Exp] += iExpKnife
            CheckPlayerLevel
(atk)
            return;
        }
        
        if(
szWpn[0]=='g' && szWpn[1]=='r')
        {
            
gData[atk][Data_Nade]++
            
gData[atk][Data_Exp] += iExpGrenade
            CheckPlayerLevel
(atk)
            return;
        }
        
        
CheckPlayerLevel(atk)
    }
}

public 
zp_fw_core_infect_post(vicatk)
{
    if(
flag_get(g_IsConnectedvic))
    {
        
gData[vic][Data_Deaths]++
    }
    
    if((
atk != vic) && flag_get(g_IsConnectedatk))
    {
        
gData[atk][Data_Kills]++
        
gData[atk][Data_Exp] += iExpKill
        CheckPlayerLevel
(atk)
    }
}

public 
OnPlayerPreThink(id)
{
    static 
Float:ctimectime get_gametime();
    if(
fLastHud[id] > ctime) return;
    
    
fLastHud[id] = ctime+1.0
    
    
if(!is_user_alive(id))
    {
        static 
iSpeciSpec entity_get_int(idEV_INT_iuser2);
        if(!
is_user_alive(iSpec)) return;
        
        
set_hudmessage(128128128HUD_STATS_XHUD_STATS_Y06.01.10.60.5, -1)
        
ShowSyncHudMsg(idiHudStats"SPECTATING: %s | COUNTRY: %s^nHP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s"gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpecEV_FL_health), entity_get_float(iSpecEV_FL_armorvalue), zp_ammopacks_get(iSpec), gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1], szRanks[gData[iSpec][Data_Level]])
        return;
    }
    
    
set_hudmessage(41284HUD_STATS_XHUD_STATS_Y06.01.10.60.5, -1)
    
ShowSyncHudMsg(idiHudStats"HP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s^nCOUNTRY: %s"entity_get_float(idEV_FL_health), entity_get_float(idEV_FL_armorvalue), zp_ammopacks_get(id), gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], szRanks[gData[id][Data_Level]], gData[id][Data_Country])
}

public 
_get_user_exp(id)
{
    return 
gData[id][Data_Exp];
}

public 
_set_user_exp(idamount)
{
    
gData[id][Data_Exp] = amount
}

public 
_get_user_playtime(id)
{
    return 
gData[id][Data_PlayTime];
}

public 
_set_user_playtime(idamount)
{
    
gData[id][Data_PlayTime] = amount
}

public 
_get_user_level(id)
{
    return 
gData[id][Data_Level];
}

public 
_set_user_level(idamount)
{
    
gData[id][Data_Level] = amount
}

public 
_get_user_deaths(id)
{
    return 
gData[id][Data_Deaths];
}

public 
_set_user_deaths(idamount)
{
    
gData[id][Data_Deaths] = amount
}

public 
_get_user_frags(id)
{
    return 
gData[id][Data_Kills];
}

public 
_set_user_frags(idamount)
{
    
gData[id][Data_Kills] = amount
}

public 
_get_user_headshot(id)
{
    return 
gData[id][Data_HeadShot];
}

public 
_set_user_headshot(idamount)
{
    
gData[id][Data_HeadShot] = amount
}

public 
_get_user_knife(id)
{
    return 
gData[id][Data_Knife];
}

public 
_set_user_knife(idamount)
{
    
gData[id][Data_Knife] = amount
}

public 
_get_user_nade(id)
{
    return 
gData[id][Data_Nade];
}

public 
_set_user_nade(idamount)
{
    
gData[id][Data_Nade] = amount
}

public 
_get_user_nemesis(id)
{
    return 
gData[id][Data_NemKills];
}

public 
_set_user_nemesis(idamount)
{
    
gData[id][Data_NemKills] = amount
}

public 
_get_user_survivor(id)
{
    return 
gData[id][Data_SurKills];
}

public 
_set_user_survivor(idamount)
{
    
gData[id][Data_SurKills] = amount
}

public 
_reset_user_data(id)
{
    
gData[id][Data_Exp] = 0
    gData
[id][Data_Kills] = 0
    gData
[id][Data_Deaths] = 0
    gData
[id][Data_HeadShot] = 0
    gData
[id][Data_Knife] = 0
    gData
[id][Data_Nade] = 0
    gData
[id][Data_NemKills] = 0
    gData
[id][Data_SurKills] = 0
    gData
[id][Data_PlayTime] = 0
    gData
[id][Data_Level] = 0
}

public 
_get_user_rank(id)
{
    return 
SortPlayerRank(id);
}

GetTimeFormat(secondsszTime[], len)
{
    new 
dayshoursminutes
    days 
seconds 86400;
    
hours = ( seconds 3600 ) % 24;
    
minutes = ( seconds 60 ) % 60;
    
seconds seconds 60;
    
    if(
days)
    {
        
formatex(szTimelen"%dD %dH %dM %dS"dayshoursminutesseconds)
        return;
    }
    
    if(
hours)
    {
        
formatex(szTimelen"%dH %dM %dS"hoursminutesseconds)
        return;
    }
    
    if(
minutes)
    {
        
formatex(szTimelen"%dM %dS"minutesseconds)
        return;
    }
    
    if(
seconds)
    {
        
formatex(szTimelen"%dS"seconds)
    }
}

GetPlayerStats(idcaller)
{
    new 
szMotd2[1536], len
    szMotd2
[0] = 0
    
    add
(szMotd2charsmax(szMotd2),
    
"<html><style>\
    body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
    .t{color:#808080;text-align:left; }\
    #h{background: #336600 url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
    #p{color:#00CCCC;}\
    #n{color:#fff;}\
    </style><body>\
    <table cellspacing=0 width=100% class=t>"
)
    
    
add(szMotd2charsmax(szMotd2),
    
"<tr><td id=h width=7%>DATA</td>\
    <td id=h>VALUE</td></tr>"
)
    
    
len strlen(szMotd2)

    new 
iSecszTimeFormat[32], iRankiPacks
    iSec 
get_user_time(id)+gData[id][Data_PlayTime]
    
GetTimeFormat(iSecszTimeFormat31)
    
iRank SortPlayerRank(id)
    
iPacks zp_get_user_ammo_packs(id)
    
replace_all(gData[id][Data_Name], 31"<""&lt")
    
replace_all(gData[id][Data_Name], 31">""&gt")
    
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Name</td>\<td>%s</td>"gData[id][Data_Name])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>SteamID</td>\<td>%s</td>"gData[id][Data_Steamid])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Country</td>\<td>%s</td>"gData[id][Data_Country])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Rank</td>\<td>%d of %d</td>"iRankiTotalEntries)
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Packs</td>\<td>%d</td>"iPacks)
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>EXP</td>\<td>%d</td>"gData[id][Data_Exp])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Level</td>\<td>%s</td>"szRanks[gData[id][Data_Level]])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Kills</td>\<td>%d</td>"gData[id][Data_Kills])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Deaths</td>\<td>%d</td>"gData[id][Data_Deaths])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Headshot</td>\<td>%d</td>"gData[id][Data_HeadShot])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Knife</td>\<td>%d</td>"gData[id][Data_Knife])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Grenade</td>\<td>%d</td>"gData[id][Data_Nade])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Nemesis</td>\<td>%d</td>"gData[id][Data_NemKills])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Survivor</td>\<td>%d</td>"gData[id][Data_SurKills])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Online</td>\<td>%s</td>"szTimeFormat)
    
    
add(szMotd2charsmax(szMotd2), "</table></body></html>")
    
show_motd(callerszMotd2"PLAYER STATS")
}

CheckPlayerLevel(id)
{
    while((
gData[id][Data_Exp] >= iEXP[gData[id][Data_Level]+1]))
    {
        
gData[id][Data_Level]++
        
client_print_color(0id"^4%s^1 has been promoted to the rank of^4 %s^1 with^4 %d^1 EXP."gData[id][Data_Name], szRanks[gData[id][Data_Level]], gData[id][Data_Exp])
        
ExecuteForward(gForward[Forward_Levelup], gForward[Forward_Result], idgData[id][Data_Level], gData[id][Data_Exp])
    }
}

LoadPlayerData(id)
{
    new 
szKey[50], szData[128]
    
formatex(szKey49"%s#EXP"gData[id][Data_Steamid])
    if(
nvault_get(iVaultHandleszKeyszData127))
    {
        new 
szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8]
        
parse(szDataszExp7szKills7szDeaths7szHeadShot7szKnife7szNade7szNemKill7szSurKill7szPlayTime7szLevel7)
        
        
gData[id][Data_Exp] = str_to_num(szExp)
        
gData[id][Data_Kills] = str_to_num(szKills)
        
gData[id][Data_Deaths] = str_to_num(szDeaths)
        
gData[id][Data_HeadShot] = str_to_num(szHeadShot)
        
gData[id][Data_Knife] = str_to_num(szKnife)
        
gData[id][Data_Nade] = str_to_num(szNade)
        
gData[id][Data_NemKills] = str_to_num(szNemKill)
        
gData[id][Data_SurKills] = str_to_num(szSurKill)
        
gData[id][Data_PlayTime] = str_to_num(szPlayTime)
        
gData[id][Data_Level] = str_to_num(szLevel)
    }
    
bIsLoaded[id] = true
    ExecuteForward
(gForward[Forward_Login], gForward[Forward_Result], idgData[id][Data_Level], gData[id][Data_Exp])
}

SavePlayerData(id)
{
    new 
szKey[50], szData[128]
    
formatex(szKey49"%s#EXP"gData[id][Data_Steamid])
    
replace_all(gData[id][Data_Name], 31" ""#")
    
formatex(szData127"%d %d %d %d %d %d %d %d %d %d %s"gData[id][Data_Exp], gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_HeadShot], gData[id][Data_Knife], gData[id][Data_Nade], gData[id][Data_NemKills], gData[id][Data_SurKills], gData[id][Data_PlayTime], gData[id][Data_Level], gData[id][Data_Name])
    
nvault_set(iVaultHandleszKeyszData)
    
bIsLoaded[id] = false
}

FormatGlobalTopTen()
{
    
enum _:VaultData
    
{
        
VD_Key[64],
        
VD_Value
    
}
    
    const 
MAX_ENTRIES 10
    
new vault nvault_util_open(szVaultName)
    new Array:
entries ArrayCreate(VaultData)
    new 
sizeEntries
    
new numEntries nvault_util_count(vault)
    new 
data[VaultData], value[128], data2[VaultData]
    
    for(new 
0postimestampnumEntriesi++)
    {
        
pos nvault_util_read(vaultposdata[VD_Key], charsmax(data[VD_Key]), valuecharsmax(value), timestamp)
        
data[VD_Value] = str_to_num(value)
        
        if(
sizeEntries == 0)
        {
            
ArrayPushArray(entriesdata)
            
sizeEntries++;
        }
        else
        {
            for(
timestamp 0timestamp <= sizeEntriestimestamp++)
            {
                if(
timestamp == sizeEntries)
                {
                    if(
sizeEntries MAX_ENTRIES)
                    {
                        
ArrayPushArray(entriesdata)
                        
sizeEntries++;
                    }
                    
                    break;
                }
                
                
ArrayGetArray(entriestimestampdata2)
                
                if(
data[VD_Value] >= data2[VD_Value])
                {
                    
ArrayInsertArrayBefore(entriestimestampdata)
                    
                    if(
sizeEntries MAX_ENTRIES)
                    {
                        
sizeEntries++;
                    }
                    else
                    {
                        
ArrayDeleteItem(entriessizeEntries)
                    }
                    
                    break;
                }
            }
        }
    }
    
    
nvault_util_close(vault)

    new 
len
    szMotd
[0] = 0
    
    add
(szMotdcharsmax(szMotd),
    
"<html><style>\
    body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
    .t{color:#808080;text-align:left; }\
    #h{background: #0066CC url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
    #p{color:#D41313;}\
    #n{color:#fff;}\
    </style><body>\
    <table cellspacing=0 width=100% class=t>"
)
    
    
add(szMotdcharsmax(szMotd),
    
"<tr><td id=h width=7%>#</td>\
    <td id=h>Name</td>\
    <td id=h>EXP</td>\
    <td id=h>Kills</td>\
    <td id=h>Deaths</td>\
    <td id=h>Online</td></tr>"
)
    
    
len strlen(szMotd)
    
    for(new 
0sizeEntriesi++)
    {
        
ArrayGetArray(entriesidata)
        
data[VD_Key][20] = 0
        
        
new szDataNew[128]
        
nvault_get(iVaultHandledata[VD_Key], szDataNewcharsmax(szDataNew))
        
        new 
szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8], szName3[32]
        
parse(szDataNewszExp7szKills7szDeaths7szHeadShot7szKnife7szNade7szNemKill7szSurKill7szPlayTime7szLevel7szName331)
        
        new 
iSecszOnline[32]
        
replace_all(szName331"#"" ")
        
iSec str_to_num(szPlayTime)
        
GetTimeFormat(iSecszOnline31)
        
        
replace_all(szName3charsmax(szName3), "<""&lt")
        
replace_all(szName3charsmax(szName3), ">""&gt")
        
        
len += formatex(szMotd[len], charsmax(szMotd)-len,
        
"<tr><td id=p>%d</td>\
        <td id=n>%s</td>\
        <td>%s</td>\
        <td>%s</td>\
        <td>%s</td>\
        <td>%s</td>"
, (i+1), szName3szExpszKillsszDeathsszOnline)
    }
    
    
add(szMotdcharsmax(szMotd), "</table></body></html>")
    
ArrayDestroy(entries)
}

SortPlayerRank(id)
{
    new 
szKey[50]
    
formatex(szKey49"%s#EXP"gData[id][Data_Steamid])
    
    
enum _:VaultData
    
{
        
VD_Key[64],
        
VD_Value
    
}
    
    new 
vault nvault_util_open(szVaultName)
    new Array:
entries ArrayCreate(VaultData)
    new 
sizeEntries
    
new numEntries nvault_util_count(vault)
    new 
data[VaultData], value[128], data2[VaultData]
    
    for(new 
0postimestampnumEntriesi++)
    {
        
pos nvault_util_read(vaultposdata[VD_Key], charsmax(data[VD_Key]), valuecharsmax(value), timestamp)
        
data[VD_Value] = str_to_num(value)
        
        if(
sizeEntries == 0)
        {
            
ArrayPushArray(entriesdata)
            
sizeEntries++;
        }
        else
        {
            for(
timestamp 0timestamp <= sizeEntriestimestamp++)
            {
                if(
timestamp == sizeEntries)
                {
                    if(
sizeEntries numEntries)
                    {
                        
ArrayPushArray(entriesdata)
                        
sizeEntries++;
                    }
                    
                    break;
                }
                
                
ArrayGetArray(entriestimestampdata2)
                
                if(
data[VD_Value] >= data2[VD_Value])
                {
                    
ArrayInsertArrayBefore(entriestimestampdata)
                    
                    if(
sizeEntries numEntries)
                    {
                        
sizeEntries++;
                    }
                    else
                    {
                        
ArrayDeleteItem(entriessizeEntries)
                    }
                    
                    break;
                }
            }
        }
    }
    
    
nvault_util_close(vault)
    
iTotalEntries sizeEntries
    
    
for(new 0sizeEntriesi++)
    {
        
ArrayGetArray(entriesidata)
        
data[VD_Key][20] = 0
        
if(equal(data[VD_Key],szKey))
        {
            
gData[id][Data_Rank] = i+1
            
break;
        }
    }
    
    
ArrayDestroy(entries)
    return 
gData[id][Data_Rank];

off: what is the difference between Ham_Player_PreThink or FM_PlayerPreThink? or it is the same?

Last edited by wicho; 03-31-2015 at 17:16.
wicho is offline
yokomo
Surprise Ascot!
Join Date: May 2010
Location: Malaysia
Old 03-31-2015 , 17:35   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #6

Quote:
Originally Posted by wicho View Post
to 5.0 but not tested..

PHP Code:
#include <amxmodx>
#include <engine>
#include <hamsandwich>
#include <nvault_util>
#include <geoip>
#include <zp50_core> 
#include <zp50_class_nemesis> 
#include <zp50_class_survivor> 
#include <zp50_ammopacks> 

new const szRanks[][] = 
{
    
"Private (0)"// 0
    
"Private 1st Class (1)"// 1
    
"Corporal (2)"// 2
    
"Sergeant (3)"// 3
    
"Staff Sergeant (4)"// 4
    
"Sergeant 1st Class (5)"// 5
    
"Master Sergeant (6)"// 6
    
"Sergeant Major (7)"// 7
    
"2nd Lieutenant (8)"// 8
    
"1st Lieutenant (9)"// 9
    
"Captain (10)"// 10
    
"Major (11)"// 11
    
"Lieutenant Colonel (12)"// 12
    
"Colonel (13)"// 13
    
"Brigadier General (14)"// 14
    
"Major General (15)"// 15
    
"Lieutenant General (16)"// 16
    
"General (17)"// 17
    
"General of the Army (18)"// 18
    
"Otai (19)" //19 max level only cheater may achieve this rank
}

new const 
iEXP[] = 
{
    
0// 0
    
50// 1
    
100// 2
    
200// 3
    
400// 4
    
800// 5
    
1600// 6
    
3200// 7
    
6400// 8
    
12800// 9
    
25600// 10
    
51200// 11
    
102400// 12
    
204800// 13
    
409600// 14
    
819200// 15
    
1638400// 16
    
3276800// 17
    
6553600// 18
    
9999999 //19 max level only cheater may achieve this rank
}

enum _:Player_Data
{
    
Data_Steamid[35],
    
Data_Name[32],
    
Data_Exp,
    
Data_Kills,
    
Data_Deaths,
    
Data_HeadShot,
    
Data_Knife,
    
Data_Nade,
    
Data_NemKills,
    
Data_SurKills,
    
Data_PlayTime,
    
Data_Level,
    
Data_Country[46],
    
Data_Rank,
    
MAX_PLAYER_DATA
}

enum _:Forward_Data
{
    
Forward_Login,
    
Forward_Levelup,
    
Forward_Result,
    
MAX_FORWARD_DATA
}

#define flag_get(%1,%2) (%1 & (1 << (%2 & 31)))
#define flag_set(%1,%2) %1 |= (1 << (%2 & 31))
#define flag_unset(%1,%2) %1 &= ~(1 << (%2 & 31))

new g_IsConnected

new iVaultHandlegData[33][MAX_PLAYER_DATA], bool:bIsLoaded[33], iHudStatsFloat:fLastHud[33], szMotd[1536], gForward[MAX_FORWARD_DATA], Float:fLastCmdiTotalEntries
const iExpKill 3
const iExpHeadShot 3
const iExpKnife 5
const iExpGrenade 8
const iExpNemKill 20
const iExpSurKill 15
const Float:HUD_STATS_X = -1.0
const Float:HUD_STATS_Y 0.8
new const szVaultName[] = "zpexpmod"
#define PLUGIN_VERSION "0.0.1"
#define CVAR_EXP_VERSION "zp_simple_stats"

//Uncomment this to update motd.txt on map loaded to show global top-10 players.
//#define UPDATE_MOTD

//Uncomment this to enable nvault prune.
#define PRUNE_DATABASE

#if defined UPDATE_MOTD
new const szFileMotd[] = "motd.txt"
#endif

#if defined PRUNE_DATABASE
const iExpiredDays 15
#endif

public plugin_natives()
{
    
register_native("xp_get_user_exp","_get_user_exp",1)
    
register_native("xp_set_user_exp","_set_user_exp",1)
    
    
register_native("xp_get_user_playtime","_get_user_playtime",1)
    
register_native("xp_set_user_playtime","_set_user_playtime",1)
    
    
register_native("xp_get_user_level","_get_user_level",1)
    
register_native("xp_set_user_level","_set_user_level",1)
    
    
register_native("xp_get_user_deaths","_get_user_deaths",1)
    
register_native("xp_set_user_deaths","_set_user_deaths",1)
    
    
register_native("xp_get_user_frags","_get_user_frags",1)
    
register_native("xp_set_user_frags","_set_user_frags",1)
    
    
register_native("xp_get_user_headshot","_get_user_headshot",1)
    
register_native("xp_set_user_headshot","_set_user_headshot",1)
    
    
register_native("xp_get_user_knife","_get_user_knife",1)
    
register_native("xp_set_user_knife","_set_user_knife",1)
    
    
register_native("xp_get_user_nade","_get_user_nade",1)
    
register_native("xp_set_user_nade","_set_user_nade",1)
    
    
register_native("xp_get_user_nemesis","_get_user_nemesis",1)
    
register_native("xp_set_user_nemesis","_set_user_nemesis",1)
    
    
register_native("xp_get_user_survivor","_get_user_survivor",1)
    
register_native("xp_set_user_survivor","_set_user_survivor",1)
    
    
register_native("xp_reset_user_data","_reset_user_data",1)
    
register_native("xp_get_user_rank","_get_user_rank",1)
}

public 
plugin_init()
{
    
register_plugin("ZP Simple Stats"PLUGIN_VERSION"wbyokomo")
    
    
register_event("DeathMsg""OnDeathMsg""a"//use deathmsg easy to trace weapon and hitplace
    
    
iHudStats CreateHudSyncObj()
    
RegisterHam(Ham_Player_PreThink"player""OnPlayerPreThink"//no need for csbot
    
    
register_clcmd("say /stats" "CmdStats")
    
register_clcmd("say /rank""CmdShowRank")
    
register_clcmd("say /top15""CmdTopExpGlobal")
    
register_clcmd("say /top10""CmdTopExpGlobal")
    
register_clcmd("say /globaltop""CmdTopExpGlobal")
    
register_clcmd("say /onlinetop""CmdTopExpOnline")
    
    
register_clcmd("say_team /stats" "CmdStats")
    
register_clcmd("say_team /rank""CmdShowRank")
    
register_clcmd("say_team /top15""CmdTopExpGlobal")
    
register_clcmd("say_team /top10""CmdTopExpGlobal")
    
register_clcmd("say_team /globaltop""CmdTopExpGlobal")
    
register_clcmd("say_team /onlinetop""CmdTopExpOnline")
    
    
gForward[Forward_Login] = CreateMultiForward("xp_user_login"ET_IGNOREFP_CELLFP_CELLFP_CELL//xp_user_login(player, level, exp)
    
gForward[Forward_Levelup] = CreateMultiForward("xp_user_levelup"ET_IGNOREFP_CELLFP_CELLFP_CELL//xp_user_levelup(player, level, exp)
    
    
register_cvar(CVAR_EXP_VERSIONPLUGIN_VERSIONFCVAR_SERVER|FCVAR_SPONLY)
    
set_cvar_string(CVAR_EXP_VERSIONPLUGIN_VERSION)
}

public 
plugin_cfg()
{
    
iVaultHandle nvault_open(szVaultName)
    
    if(
iVaultHandle == INVALID_HANDLE)
    {
        
set_fail_state("Error opening nVault file [%s]"szVaultName)
    }
    else
    {
        
server_print("Database [%s] successfully loaded..."szVaultName)
        
        
#if defined PRUNE_DATABASE
        
nvault_prune(iVaultHandle0get_systime() - (86400 iExpiredDays))
        
#endif
        
        
FormatGlobalTopTen()
        
        
#if defined UPDATE_MOTD
        
if(file_exists(szFileMotd))
        {
            if(
delete_file(szFileMotd))
            {
                if(
write_file(szFileMotdszMotd, -1)) server_print("File [%s] has been updated..."szFileMotd);
            }
        }
        
#endif
    
}
    
    
set_task(0.6"TurnOfDefHud")
}

public 
TurnOfDefHud()
{
    if(
cvar_exists("zp_hud_display")) set_cvar_num("zp_hud_display"0);
    else 
set_fail_state("This plugin compatible only with ZP4.3Fix5a. Download 'zp_plugin_43_patched.zip' at http://forums.alliedmods.net/showthread.php?t=72505");
}

public 
plugin_end()
{
    
nvault_close(iVaultHandle)
}

public 
client_putinserver(id)
{
    
get_user_authid(idgData[id][Data_Steamid], 34)
    
LoadPlayerData(id)
    
get_user_name(idgData[id][Data_Name], 31)
    new 
szIp[32]; get_user_ip(idszIp311);
    
geoip_country_ex(szIpgData[id][Data_Country], 45)
    if(
equali(gData[id][Data_Country],"")) copy(gData[id][Data_Country], 45"Unknown");
    
gData[id][Data_Rank] = -1
    flag_set
(g_IsConnectedid)
}

public 
client_disconnect(id)
{
    if(
bIsLoaded[id])
    {
        
gData[id][Data_PlayTime] += get_user_time(id)
        
SavePlayerData(id)
    }
    else
    {
        
log_to_file("exp_log.log""Player: %s | Steamid: %s -- failed to save data."gData[id][Data_Name], gData[id][Data_Steamid])
    }
    
    
flag_unset(g_IsConnectedid)
}

public 
client_infochanged(id)
{
    if(
flag_get(g_IsConnectedidget_user_info(id"name"gData[id][Data_Name], 31));
}

public 
CmdStats(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    new 
menu menu_create("\yPlayer Stats:""PlayerStatsMenuHandler")
    new 
szUserId[32], id2
    
for(id2=1;id2<=MaxClients;id2++)
    {
        if(!
flag_get(g_IsConnectedid2)) continue;
        
        
formatex(szUserIdcharsmax(szUserId), "%d"get_user_userid(id2))
        
menu_additem(menugData[id2][Data_Name], szUserId0)
    }
    
    
menu_display(idmenu0)
    
    return 
PLUGIN_HANDLED;
}

public 
PlayerStatsMenuHandler(idmenuitem)
{
    if(!
flag_get(g_IsConnectedid))
    {
        
menu_destroy(menu)
        return 
PLUGIN_HANDLED;
    }
    
    if(
item == MENU_EXIT)
    {
        
menu_destroy(menu)
        return 
PLUGIN_HANDLED;
    }
    
    new 
szData[6], szName[64]
    new 
_accessitem_callback
    menu_item_getinfo
(menuitem_accessszData,charsmax(szData), szName,charsmax(szName), item_callback)
    
    new 
userid str_to_num(szData)
    new 
player find_player("k"userid)
    
    if(
player && flag_get(g_IsConnectedplayer))
    {
        
GetPlayerStats(playerid)
    }
    
    
menu_destroy(menu)
    return 
PLUGIN_HANDLED;
}

public 
CmdShowRank(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    static 
Float:ctimectime get_gametime();
    if(
fLastCmd ctime)
    {
        
client_print(idprint_chat"System is busy please wait for %.1f second(s)."fLastCmd-ctime)
        return 
PLUGIN_HANDLED;
    }
    
    
fLastCmd ctime+2.0
    
new iRank SortPlayerRank(id)
    if(
iRank == -1client_print(idprint_chat"Your rank is not been saved yet, please rejoin the server.");
    else 
client_print_color(0print_team_default"^4%s^1 rank is^4 %d^1/^4%d^1 -- Kills:^4 %d^1 Deaths:^4 %d^1 Level:^4 %d^1 EXP:^4 %d^1/^4%d"gData[id][Data_Name], iRankiTotalEntriesgData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_Level], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1])
    
    return 
PLUGIN_HANDLED;
}

public 
CmdTopExpGlobal(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    static 
Float:ctimectime get_gametime();
    if(
fLastCmd ctime)
    {
        
client_print(idprint_chat"System is busy please wait for %.1f second(s)."fLastCmd-ctime)
        return 
PLUGIN_HANDLED;
    }
    
    
fLastCmd ctime+2.0
    show_motd
(idszMotd"TOP-10 Players (GLOBAL)")
    
    return 
PLUGIN_HANDLED;
}

public 
CmdTopExpOnline(id)
{
    if(!
flag_get(g_IsConnectedid)) return PLUGIN_HANDLED;
    
    if(!
bIsLoaded[id])
    {
        
client_print(idprint_chat"Sorry! failed to load your stats. Please rejoin the server :)")
        return 
PLUGIN_HANDLED;
    }
    
    static 
Float:ctimectime get_gametime();
    if(
fLastCmd ctime)
    {
        
client_print(idprint_chat"System is busy please wait for %.1f second(s)."fLastCmd-ctime)
        return 
PLUGIN_HANDLED;
    }
    
    
fLastCmd ctime+2.0
    
static Sort[33][2]
    new 
players[32], numcountindex
    get_players
(playersnum)
    
    for(new 
0numi++)
    {
        
index players[i]
        
Sort[count][0] = index
        Sort
[count][1] = gData[index][Data_Exp]
        
count++
    }
    
    
SortCustom2D(Sortcount"CompareEXP")
    
    new 
clamp(count010)
    new 
kindexszMotd2[1536], len
    szMotd2
[0] = 0
    
    add
(szMotd2charsmax(szMotd2),
    
"<html><style>\
    body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
    .t{color:#808080;text-align:left; }\
    #h{background: #0066CC url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
    #p{color:#D41313;}\
    #n{color:#fff;}\
    </style><body>\
    <table cellspacing=0 width=100% class=t>"
)
    
    
add(szMotd2charsmax(szMotd2),
    
"<tr><td id=h width=7%>#</td>\
    <td id=h>Name</td>\
    <td id=h>EXP</td>\
    <td id=h>Kills</td>\
    <td id=h>Deaths</td>\
    <td id=h>Online</td></tr>"
)
    
    
len strlen(szMotd2)
    
    for(new 
0yx++)
    {
        
kindex Sort[x][0]
        new 
iSecszTimeFormat[32]
        
iSec get_user_time(kindex)+gData[kindex][Data_PlayTime]
        
GetTimeFormat(iSecszTimeFormat31)
        
        
replace_all(gData[kindex][Data_Name], 31"<""&lt")
        
replace_all(gData[kindex][Data_Name], 31">""&gt")
        
        
len += formatex(szMotd2[len], charsmax(szMotd2)-len,
        
"<tr><td id=p>%d</td>\
        <td id=n>%s</td>\
        <td>%d</td>\
        <td>%d</td>\
        <td>%d</td>\
        <td>%s</td>"
, (x+1), gData[kindex][Data_Name], gData[kindex][Data_Exp], gData[kindex][Data_Kills], gData[kindex][Data_Deaths], szTimeFormat)
    }
    
    
add(szMotd2charsmax(szMotd2), "</table></body></html>")
    
show_motd(idszMotd2"TOP-10 Players (ONLINE)")
    
    return 
PLUGIN_HANDLED;
}

public 
CompareEXP(elem1[], elem2[])
{
    if(
elem1[1] > elem2[1]) return -1;
    else if(
elem1[1] < elem2[1]) return 1;
    
    return 
0;
}

public 
OnDeathMsg()
{
    new 
atkvichsszWpn[4]
    
atk read_data(1)
    
vic read_data(2)
    
hs read_data(3)
    
read_data(4szWpn3)
    
    if(
flag_get(g_IsConnectedvic))
    {
        
gData[vic][Data_Deaths]++
    }
    
    if((
atk != vic) && flag_get(g_IsConnectedatk))
    {
        
gData[atk][Data_Kills]++
        
gData[atk][Data_Exp] += iExpKill
        
        
if(hs)
        {
            
gData[atk][Data_HeadShot]++
            
gData[atk][Data_Exp] += iExpHeadShot
        
}
        
        if(
zp_class_nemesis_get(vic))
        {
            
gData[atk][Data_NemKills]++
            
gData[atk][Data_Exp] += iExpNemKill
        
}
        else if(
zp_class_survivor_get(vic))
        {
            
gData[atk][Data_SurKills]++
            
gData[atk][Data_Exp] += iExpSurKill
        
}
        
        if(
szWpn[0]=='k' && szWpn[1]=='n')
        {
            
gData[atk][Data_Knife]++
            
gData[atk][Data_Exp] += iExpKnife
            CheckPlayerLevel
(atk)
            return;
        }
        
        if(
szWpn[0]=='g' && szWpn[1]=='r')
        {
            
gData[atk][Data_Nade]++
            
gData[atk][Data_Exp] += iExpGrenade
            CheckPlayerLevel
(atk)
            return;
        }
        
        
CheckPlayerLevel(atk)
    }
}

public 
zp_fw_core_infect_post(vicatk)
{
    if(
flag_get(g_IsConnectedvic))
    {
        
gData[vic][Data_Deaths]++
    }
    
    if((
atk != vic) && flag_get(g_IsConnectedatk))
    {
        
gData[atk][Data_Kills]++
        
gData[atk][Data_Exp] += iExpKill
        CheckPlayerLevel
(atk)
    }
}

public 
OnPlayerPreThink(id)
{
    static 
Float:ctimectime get_gametime();
    if(
fLastHud[id] > ctime) return;
    
    
fLastHud[id] = ctime+1.0
    
    
if(!is_user_alive(id))
    {
        static 
iSpeciSpec entity_get_int(idEV_INT_iuser2);
        if(!
is_user_alive(iSpec)) return;
        
        
set_hudmessage(128128128HUD_STATS_XHUD_STATS_Y06.01.10.60.5, -1)
        
ShowSyncHudMsg(idiHudStats"SPECTATING: %s | COUNTRY: %s^nHP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s"gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpecEV_FL_health), entity_get_float(iSpecEV_FL_armorvalue), zp_ammopacks_get(iSpec), gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1], szRanks[gData[iSpec][Data_Level]])
        return;
    }
    
    
set_hudmessage(41284HUD_STATS_XHUD_STATS_Y06.01.10.60.5, -1)
    
ShowSyncHudMsg(idiHudStats"HP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s^nCOUNTRY: %s"entity_get_float(idEV_FL_health), entity_get_float(idEV_FL_armorvalue), zp_ammopacks_get(id), gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], szRanks[gData[id][Data_Level]], gData[id][Data_Country])
}

public 
_get_user_exp(id)
{
    return 
gData[id][Data_Exp];
}

public 
_set_user_exp(idamount)
{
    
gData[id][Data_Exp] = amount
}

public 
_get_user_playtime(id)
{
    return 
gData[id][Data_PlayTime];
}

public 
_set_user_playtime(idamount)
{
    
gData[id][Data_PlayTime] = amount
}

public 
_get_user_level(id)
{
    return 
gData[id][Data_Level];
}

public 
_set_user_level(idamount)
{
    
gData[id][Data_Level] = amount
}

public 
_get_user_deaths(id)
{
    return 
gData[id][Data_Deaths];
}

public 
_set_user_deaths(idamount)
{
    
gData[id][Data_Deaths] = amount
}

public 
_get_user_frags(id)
{
    return 
gData[id][Data_Kills];
}

public 
_set_user_frags(idamount)
{
    
gData[id][Data_Kills] = amount
}

public 
_get_user_headshot(id)
{
    return 
gData[id][Data_HeadShot];
}

public 
_set_user_headshot(idamount)
{
    
gData[id][Data_HeadShot] = amount
}

public 
_get_user_knife(id)
{
    return 
gData[id][Data_Knife];
}

public 
_set_user_knife(idamount)
{
    
gData[id][Data_Knife] = amount
}

public 
_get_user_nade(id)
{
    return 
gData[id][Data_Nade];
}

public 
_set_user_nade(idamount)
{
    
gData[id][Data_Nade] = amount
}

public 
_get_user_nemesis(id)
{
    return 
gData[id][Data_NemKills];
}

public 
_set_user_nemesis(idamount)
{
    
gData[id][Data_NemKills] = amount
}

public 
_get_user_survivor(id)
{
    return 
gData[id][Data_SurKills];
}

public 
_set_user_survivor(idamount)
{
    
gData[id][Data_SurKills] = amount
}

public 
_reset_user_data(id)
{
    
gData[id][Data_Exp] = 0
    gData
[id][Data_Kills] = 0
    gData
[id][Data_Deaths] = 0
    gData
[id][Data_HeadShot] = 0
    gData
[id][Data_Knife] = 0
    gData
[id][Data_Nade] = 0
    gData
[id][Data_NemKills] = 0
    gData
[id][Data_SurKills] = 0
    gData
[id][Data_PlayTime] = 0
    gData
[id][Data_Level] = 0
}

public 
_get_user_rank(id)
{
    return 
SortPlayerRank(id);
}

GetTimeFormat(secondsszTime[], len)
{
    new 
dayshoursminutes
    days 
seconds 86400;
    
hours = ( seconds 3600 ) % 24;
    
minutes = ( seconds 60 ) % 60;
    
seconds seconds 60;
    
    if(
days)
    {
        
formatex(szTimelen"%dD %dH %dM %dS"dayshoursminutesseconds)
        return;
    }
    
    if(
hours)
    {
        
formatex(szTimelen"%dH %dM %dS"hoursminutesseconds)
        return;
    }
    
    if(
minutes)
    {
        
formatex(szTimelen"%dM %dS"minutesseconds)
        return;
    }
    
    if(
seconds)
    {
        
formatex(szTimelen"%dS"seconds)
    }
}

GetPlayerStats(idcaller)
{
    new 
szMotd2[1536], len
    szMotd2
[0] = 0
    
    add
(szMotd2charsmax(szMotd2),
    
"<html><style>\
    body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
    .t{color:#808080;text-align:left; }\
    #h{background: #336600 url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
    #p{color:#00CCCC;}\
    #n{color:#fff;}\
    </style><body>\
    <table cellspacing=0 width=100% class=t>"
)
    
    
add(szMotd2charsmax(szMotd2),
    
"<tr><td id=h width=7%>DATA</td>\
    <td id=h>VALUE</td></tr>"
)
    
    
len strlen(szMotd2)

    new 
iSecszTimeFormat[32], iRankiPacks
    iSec 
get_user_time(id)+gData[id][Data_PlayTime]
    
GetTimeFormat(iSecszTimeFormat31)
    
iRank SortPlayerRank(id)
    
iPacks zp_get_user_ammo_packs(id)
    
replace_all(gData[id][Data_Name], 31"<""&lt")
    
replace_all(gData[id][Data_Name], 31">""&gt")
    
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Name</td>\<td>%s</td>"gData[id][Data_Name])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>SteamID</td>\<td>%s</td>"gData[id][Data_Steamid])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Country</td>\<td>%s</td>"gData[id][Data_Country])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Rank</td>\<td>%d of %d</td>"iRankiTotalEntries)
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Packs</td>\<td>%d</td>"iPacks)
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>EXP</td>\<td>%d</td>"gData[id][Data_Exp])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Level</td>\<td>%s</td>"szRanks[gData[id][Data_Level]])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Kills</td>\<td>%d</td>"gData[id][Data_Kills])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Deaths</td>\<td>%d</td>"gData[id][Data_Deaths])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Headshot</td>\<td>%d</td>"gData[id][Data_HeadShot])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Knife</td>\<td>%d</td>"gData[id][Data_Knife])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Grenade</td>\<td>%d</td>"gData[id][Data_Nade])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Nemesis</td>\<td>%d</td>"gData[id][Data_NemKills])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Survivor</td>\<td>%d</td>"gData[id][Data_SurKills])
    
len += formatex(szMotd2[len], charsmax(szMotd2)-len"<tr><td id=p>Online</td>\<td>%s</td>"szTimeFormat)
    
    
add(szMotd2charsmax(szMotd2), "</table></body></html>")
    
show_motd(callerszMotd2"PLAYER STATS")
}

CheckPlayerLevel(id)
{
    while((
gData[id][Data_Exp] >= iEXP[gData[id][Data_Level]+1]))
    {
        
gData[id][Data_Level]++
        
client_print_color(0id"^4%s^1 has been promoted to the rank of^4 %s^1 with^4 %d^1 EXP."gData[id][Data_Name], szRanks[gData[id][Data_Level]], gData[id][Data_Exp])
        
ExecuteForward(gForward[Forward_Levelup], gForward[Forward_Result], idgData[id][Data_Level], gData[id][Data_Exp])
    }
}

LoadPlayerData(id)
{
    new 
szKey[50], szData[128]
    
formatex(szKey49"%s#EXP"gData[id][Data_Steamid])
    if(
nvault_get(iVaultHandleszKeyszData127))
    {
        new 
szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8]
        
parse(szDataszExp7szKills7szDeaths7szHeadShot7szKnife7szNade7szNemKill7szSurKill7szPlayTime7szLevel7)
        
        
gData[id][Data_Exp] = str_to_num(szExp)
        
gData[id][Data_Kills] = str_to_num(szKills)
        
gData[id][Data_Deaths] = str_to_num(szDeaths)
        
gData[id][Data_HeadShot] = str_to_num(szHeadShot)
        
gData[id][Data_Knife] = str_to_num(szKnife)
        
gData[id][Data_Nade] = str_to_num(szNade)
        
gData[id][Data_NemKills] = str_to_num(szNemKill)
        
gData[id][Data_SurKills] = str_to_num(szSurKill)
        
gData[id][Data_PlayTime] = str_to_num(szPlayTime)
        
gData[id][Data_Level] = str_to_num(szLevel)
    }
    
bIsLoaded[id] = true
    ExecuteForward
(gForward[Forward_Login], gForward[Forward_Result], idgData[id][Data_Level], gData[id][Data_Exp])
}

SavePlayerData(id)
{
    new 
szKey[50], szData[128]
    
formatex(szKey49"%s#EXP"gData[id][Data_Steamid])
    
replace_all(gData[id][Data_Name], 31" ""#")
    
formatex(szData127"%d %d %d %d %d %d %d %d %d %d %s"gData[id][Data_Exp], gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_HeadShot], gData[id][Data_Knife], gData[id][Data_Nade], gData[id][Data_NemKills], gData[id][Data_SurKills], gData[id][Data_PlayTime], gData[id][Data_Level], gData[id][Data_Name])
    
nvault_set(iVaultHandleszKeyszData)
    
bIsLoaded[id] = false
}

FormatGlobalTopTen()
{
    
enum _:VaultData
    
{
        
VD_Key[64],
        
VD_Value
    
}
    
    const 
MAX_ENTRIES 10
    
new vault nvault_util_open(szVaultName)
    new Array:
entries ArrayCreate(VaultData)
    new 
sizeEntries
    
new numEntries nvault_util_count(vault)
    new 
data[VaultData], value[128], data2[VaultData]
    
    for(new 
0postimestampnumEntriesi++)
    {
        
pos nvault_util_read(vaultposdata[VD_Key], charsmax(data[VD_Key]), valuecharsmax(value), timestamp)
        
data[VD_Value] = str_to_num(value)
        
        if(
sizeEntries == 0)
        {
            
ArrayPushArray(entriesdata)
            
sizeEntries++;
        }
        else
        {
            for(
timestamp 0timestamp <= sizeEntriestimestamp++)
            {
                if(
timestamp == sizeEntries)
                {
                    if(
sizeEntries MAX_ENTRIES)
                    {
                        
ArrayPushArray(entriesdata)
                        
sizeEntries++;
                    }
                    
                    break;
                }
                
                
ArrayGetArray(entriestimestampdata2)
                
                if(
data[VD_Value] >= data2[VD_Value])
                {
                    
ArrayInsertArrayBefore(entriestimestampdata)
                    
                    if(
sizeEntries MAX_ENTRIES)
                    {
                        
sizeEntries++;
                    }
                    else
                    {
                        
ArrayDeleteItem(entriessizeEntries)
                    }
                    
                    break;
                }
            }
        }
    }
    
    
nvault_util_close(vault)

    new 
len
    szMotd
[0] = 0
    
    add
(szMotdcharsmax(szMotd),
    
"<html><style>\
    body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
    .t{color:#808080;text-align:left; }\
    #h{background: #0066CC url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
    #p{color:#D41313;}\
    #n{color:#fff;}\
    </style><body>\
    <table cellspacing=0 width=100% class=t>"
)
    
    
add(szMotdcharsmax(szMotd),
    
"<tr><td id=h width=7%>#</td>\
    <td id=h>Name</td>\
    <td id=h>EXP</td>\
    <td id=h>Kills</td>\
    <td id=h>Deaths</td>\
    <td id=h>Online</td></tr>"
)
    
    
len strlen(szMotd)
    
    for(new 
0sizeEntriesi++)
    {
        
ArrayGetArray(entriesidata)
        
data[VD_Key][20] = 0
        
        
new szDataNew[128]
        
nvault_get(iVaultHandledata[VD_Key], szDataNewcharsmax(szDataNew))
        
        new 
szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8], szName3[32]
        
parse(szDataNewszExp7szKills7szDeaths7szHeadShot7szKnife7szNade7szNemKill7szSurKill7szPlayTime7szLevel7szName331)
        
        new 
iSecszOnline[32]
        
replace_all(szName331"#"" ")
        
iSec str_to_num(szPlayTime)
        
GetTimeFormat(iSecszOnline31)
        
        
replace_all(szName3charsmax(szName3), "<""&lt")
        
replace_all(szName3charsmax(szName3), ">""&gt")
        
        
len += formatex(szMotd[len], charsmax(szMotd)-len,
        
"<tr><td id=p>%d</td>\
        <td id=n>%s</td>\
        <td>%s</td>\
        <td>%s</td>\
        <td>%s</td>\
        <td>%s</td>"
, (i+1), szName3szExpszKillsszDeathsszOnline)
    }
    
    
add(szMotdcharsmax(szMotd), "</table></body></html>")
    
ArrayDestroy(entries)
}

SortPlayerRank(id)
{
    new 
szKey[50]
    
formatex(szKey49"%s#EXP"gData[id][Data_Steamid])
    
    
enum _:VaultData
    
{
        
VD_Key[64],
        
VD_Value
    
}
    
    new 
vault nvault_util_open(szVaultName)
    new Array:
entries ArrayCreate(VaultData)
    new 
sizeEntries
    
new numEntries nvault_util_count(vault)
    new 
data[VaultData], value[128], data2[VaultData]
    
    for(new 
0postimestampnumEntriesi++)
    {
        
pos nvault_util_read(vaultposdata[VD_Key], charsmax(data[VD_Key]), valuecharsmax(value), timestamp)
        
data[VD_Value] = str_to_num(value)
        
        if(
sizeEntries == 0)
        {
            
ArrayPushArray(entriesdata)
            
sizeEntries++;
        }
        else
        {
            for(
timestamp 0timestamp <= sizeEntriestimestamp++)
            {
                if(
timestamp == sizeEntries)
                {
                    if(
sizeEntries numEntries)
                    {
                        
ArrayPushArray(entriesdata)
                        
sizeEntries++;
                    }
                    
                    break;
                }
                
                
ArrayGetArray(entriestimestampdata2)
                
                if(
data[VD_Value] >= data2[VD_Value])
                {
                    
ArrayInsertArrayBefore(entriestimestampdata)
                    
                    if(
sizeEntries numEntries)
                    {
                        
sizeEntries++;
                    }
                    else
                    {
                        
ArrayDeleteItem(entriessizeEntries)
                    }
                    
                    break;
                }
            }
        }
    }
    
    
nvault_util_close(vault)
    
iTotalEntries sizeEntries
    
    
for(new 0sizeEntriesi++)
    {
        
ArrayGetArray(entriesidata)
        
data[VD_Key][20] = 0
        
if(equal(data[VD_Key],szKey))
        {
            
gData[id][Data_Rank] = i+1
            
break;
        }
    }
    
    
ArrayDestroy(entries)
    return 
gData[id][Data_Rank];

off: what is the difference between Ham_Player_PreThink or FM_PlayerPreThink? or it is the same?
PHP Code:
RegisterHam(Ham_Player_PreThink"player""OnPlayerPreThink"//no need for csbot 
I test this plugin on Condition Zero game. Using ham we need to manually register forward for CSbot. So this forward is no need for bot. Only real player need it.

PHP Code:
public OnDeathMsg()
{
    new 
atkvichsszWpn[4]
    
atk read_data(1)
    
vic read_data(2)
    
hs read_data(3)
    
read_data(4szWpn3)
    
    if(
flag_get(g_IsConnectedvic))
    {
        
gData[vic][Data_Deaths]++
    }
    
    if((
atk != vic) && flag_get(g_IsConnectedatk)) 
That is why i don't want to use cache connected.
This:
PHP Code:
if((atk != vic) && flag_get(g_IsConnectedatk)) 
will throw an error if attacker > 32 because you don't check (1<=id<=MaxClients). So let make it simple.. just use amxx natives.. easy right?

You need to try your converted plugin in ZP50 first, i can say there will be an error.
__________________
Team-MMG CS1.6 Servers:
✅ MultiMod -- 103.179.44.152:27016
✅ Zombie Plague -- 103.179.44.152:27015
✅ Zombie Escape -- 103.179.44.152:27017
✅ Klassik Kombat -- 103.179.44.152:27018
✅ Boss-Battle -- 103.179.44.152:27019
yokomo is offline
New.ZM.Life
Veteran Member
Join Date: Sep 2014
Location: Iran
Old 03-31-2015 , 17:36   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #7

and here, to zp50, and amx mod x 1.8.2
i think it works well but as i tested offline, Country feature didnt work for me
Attached Files
File Type: sma Get Plugin or Get Source (zp_test_rank.sma - 971 views - 25.7 KB)
__________________
PLUGINS

Zombie Plague 5.0 + New Modes

Added NightCrawler Mode to ZP





New.ZM.Life is offline
yokomo
Surprise Ascot!
Join Date: May 2010
Location: Malaysia
Old 03-31-2015 , 18:08   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #8

Quote:
Originally Posted by New.ZM.Life View Post
and here, to zp50, and amx mod x 1.8.2
i think it works well but as i tested offline, Country feature didnt work for me
What do you mean 'Country feature didnt work' it show blank or what? If you tested on listenserver country name will return 'error' in amxmodx 1.8.2.

By the way i've made some modification on your ZP50 port. Please test it.
Attached Files
File Type: sma Get Plugin or Get Source (zp_test_rank.sma - 976 views - 25.7 KB)
__________________
Team-MMG CS1.6 Servers:
✅ MultiMod -- 103.179.44.152:27016
✅ Zombie Plague -- 103.179.44.152:27015
✅ Zombie Escape -- 103.179.44.152:27017
✅ Klassik Kombat -- 103.179.44.152:27018
✅ Boss-Battle -- 103.179.44.152:27019
yokomo is offline
yokomo
Surprise Ascot!
Join Date: May 2010
Location: Malaysia
Old 03-31-2015 , 20:21   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #9

I made a test version for ZP50 based on version 0.0.2. Can you test it?
Attached Files
File Type: sma Get Plugin or Get Source (zp_exp_stats_zp50.sma - 945 views - 27.0 KB)
__________________
Team-MMG CS1.6 Servers:
✅ MultiMod -- 103.179.44.152:27016
✅ Zombie Plague -- 103.179.44.152:27015
✅ Zombie Escape -- 103.179.44.152:27017
✅ Klassik Kombat -- 103.179.44.152:27018
✅ Boss-Battle -- 103.179.44.152:27019
yokomo is offline
Unknown Guy
Member
Join Date: Dec 2014
Location: Munich, Germany
Old 04-01-2015 , 05:53   Re: [ZP43Fix5a] Addon: Stats, ExpMod & Ranking System.
Reply With Quote #10

GJ I will test this

Suggestion : Can you add some upgrades like purchasing item by xp?
Unknown Guy is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 11:02.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode