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

OciXCrom's Rank System [XP|Levels|Ranks]


Post New Thread Reply   
 
Thread Tools Display Modes
Supergirl
Member
Join Date: Jul 2016
Old 02-10-2019 , 07:14   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #191

Quote:
Originally Posted by OciXCrom View Post
Well, that's basically the same as adding more ranks in the .ini file.
It's not. Maybe I didn't explain myself clearly (not an english native) so I'll try again. Basically it's something like this (taken from here). I believe that this would encourage players whose rank is already "the highest" to compete with each other. Instead of being updated every 24 hours, this should be (I believe) an automatically process (since nobody will put ranks being disputed by 100 players). Imagine that we chose top 2-10 to have a #19 rank. As soon as the player that is top 11 becomes top 10 the previously top 10 would become top 11 and rank #18 again while the new person occupying top 10 would become rank #19.

Last edited by Supergirl; 02-10-2019 at 07:26.
Supergirl is offline
OciXCrom
Veteran Member
Join Date: Oct 2013
Location: Macedonia
Old 02-10-2019 , 08:05   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #192

@LithuanianJack - try this. I used the SQL_QuoteString function in all places where the player name is used, as well as the rank and next rank fields since they can contain problematic symbols as well.

PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <nvault>
#include <sqlx>

// Comment or remove this line in order to run the plugin on a mod different than Counter-Strike.
#define USE_CSTRIKE

#if defined USE_CSTRIKE
    #include <cromchat>
    #include <csx>
#else
new CC_PREFIX[64]
#endif

#if AMXX_VERSION_NUM < 183
    #include <dhudmessage>
#endif

#include <crxranks_const>

#if !defined client_disconnected
    #define client_disconnected client_disconnect
#endif

#if !defined replace_string
    #define replace_string replace_all
#endif

new const PLUGIN_VERSION[] = "3.1a"
const Float:DELAY_ON_CONNECT 5.0
const Float:HUD_REFRESH_FREQ 1.0
const Float:DELAY_ON_CHANGE 0.1
const MAX_SQL_LENGTH 512
const MAX_QUERY_LENGTH 256
const MAX_SOUND_LENGTH 128
const MAX_SQL_PLAYER_LENGTH 64
const MAX_SQL_RANK_LENGTH CRXRANKS_MAX_RANK_LENGTH 2
const TASK_HUD 304500

#if !defined MAX_NAME_LENGTH
const MAX_NAME_LENGTH 32
#endif

new const ARG_CURRENT_XP[]          = "$current_xp$"
new const ARG_NEXT_XP[]             = "$next_xp$"
new const ARG_XP_NEEDED[]           = "$xp_needed$"
new const ARG_LEVEL[]               = "$level$"
new const ARG_NEXT_LEVEL[]          = "$next_level$"
new const ARG_RANK[]                = "$rank$"
new const ARG_NEXT_RANK[]           = "$next_rank$"
new const ARG_MAX_LEVELS[]          = "$max_levels$"
new const ARG_LINE_BREAK[]          = "$br$"
new const ARG_NAME[]                = "$name$"

new const XPREWARD_KILL[]           = "kill"
new const XPREWARD_HEADSHOT[]       = "headshot"
new const XPREWARD_TEAMKILL[]       = "teamkill"
new const XPREWARD_SUICIDE[]        = "suicide"

#if defined USE_CSTRIKE
new const XPREWARD_BOMB_PLANTED[]   = "bomb_planted"
new const XPREWARD_BOMB_DEFUSED[]   = "bomb_defused"
new const XPREWARD_BOMB_EXPLODED[]  = "bomb_exploded"
#endif

#define clr(%1) %1 == -1 ? random(256) : %1

#define HUDINFO_PARAMS clr(g_eSettings[HUDINFO_COLOR][0]), clr(g_eSettings[HUDINFO_COLOR][1]), clr(g_eSettings[HUDINFO_COLOR][2]),\
g_eSettings[HUDINFO_POSITION][0], g_eSettings[HUDINFO_POSITION][1], 00.11.00.10.1

#define XP_NOTIFIER_PARAMS_GET clr(g_eSettings[XP_NOTIFIER_COLOR_GET][0]), clr(g_eSettings[XP_NOTIFIER_COLOR_GET][1]), clr(g_eSettings[XP_NOTIFIER_COLOR_GET][2]),\
g_eSettings[XP_NOTIFIER_POSITION][0], g_eSettings[XP_NOTIFIER_POSITION][1], .holdtime g_eSettings[XP_NOTIFIER_DURATION]

#define XP_NOTIFIER_PARAMS_LOSE clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][0]), clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][1]), clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][2]),\
g_eSettings[XP_NOTIFIER_POSITION][0], g_eSettings[XP_NOTIFIER_POSITION][1], .holdtime g_eSettings[XP_NOTIFIER_DURATION]

enum _:SaveLoad
{
    
SL_SAVE_DATA,
    
SL_LOAD_DATA
}

enum _:Objects
{
    
OBJ_HUDINFO,
    
OBJ_XP_NOTIFIER
}

enum _:SaveTypes
{
    
SAVE_NICKNAME,
    
SAVE_IP,
    
SAVE_STEAMID
}

enum _:SaveMethods
{
    
SAVE_NVAULT,
    
SAVE_MYSQL
}

enum _:Sections
{
    
SECTION_NONE,
    
SECTION_SETTINGS,
    
SECTION_RANKS,
    
SECTION_XP_REWARDS
}

enum _:PlayerData
{
    
XP,
    
Level,
    
NextXP,
    
Rank[CRXRANKS_MAX_RANK_LENGTH],
    
NextRank[CRXRANKS_MAX_RANK_LENGTH],
    
HUDInfo[CRXRANKS_MAX_HUDINFO_LENGTH],
    
bool:IsOnFinalLevel,
    
bool:IsVIP,
    
bool:IsBot
}

enum _:Settings
{
    
SAVE_TYPE,
    
bool:USE_MYSQL,
    
SQL_HOST[MAX_NAME_LENGTH],
    
SQL_USER[MAX_NAME_LENGTH],
    
SQL_PASSWORD[MAX_NAME_LENGTH],
    
SQL_DATABASE[MAX_NAME_LENGTH],
    
SQL_TABLE[MAX_NAME_LENGTH],
    
LEVELUP_MESSAGE_TYPE,
    
LEVELUP_SOUND[MAX_SOUND_LENGTH],
    
bool:LEVELUP_SCREEN_FADE_ENABLED,
    
LEVELUP_SCREEN_FADE_COLOR[4],
    
LEVELDN_SOUND[MAX_SOUND_LENGTH],
    
bool:LEVELDN_SCREEN_FADE_ENABLED,
    
LEVELDN_SCREEN_FADE_COLOR[4],
    
FINAL_LEVEL_FLAGS[32],
    
FINAL_LEVEL_FLAGS_BIT,
    
VIP_FLAGS[32],
    
VIP_FLAGS_BIT,
    
VAULT_NAME[32],
    
TEAM_LOCK,
    
MINIMUM_PLAYERS,
    
bool:IGNORE_BOTS,
    
bool:USE_COMBINED_EVENTS,
    
bool:NOTIFY_ON_KILL,
    
bool:HUDINFO_ENABLED,
    
bool:HUDINFO_ALIVE_ONLY,
    
bool:HUDINFO_TEAM_LOCK,
    
bool:HUDINFO_OTHER_PLAYERS,
    
HUDINFO_COLOR[3],
    
Float:HUDINFO_POSITION[2],
    
bool:HUDINFO_USE_DHUD,
    
HUDINFO_FORMAT[CRXRANKS_MAX_HUDINFO_LENGTH],
    
HUDINFO_FORMAT_FINAL[CRXRANKS_MAX_HUDINFO_LENGTH],
    
HUDINFO_INVALID_TEXT[32],
    
bool:XP_NOTIFIER_ENABLED,
    
XP_NOTIFIER_COLOR_GET[3],
    
XP_NOTIFIER_COLOR_LOSE[3],
    
Float:XP_NOTIFIER_POSITION[2],
    
Float:XP_NOTIFIER_DURATION,
    
bool:XP_NOTIFIER_USE_DHUD
}

new 
g_eSettings[Settings]
new 
g_ePlayerData[33][PlayerData]
new 
g_szMaxLevels[CRXRANKS_MAX_XP_LENGTH]
new 
g_szSqlError[MAX_SQL_LENGTH]
new 
Handle:g_iSqlTuple
new Array:g_aLevels
new Array:g_aRankNames
new Trie:g_tSettings
new Trie:g_tXPRewards
new Trie:g_tXPRewardsVIP

new g_iVault
new g_iMaxLevels
new g_iFlagZ
new g_iScreenFade
new g_iObject[2]

new 
g_fwdUserLevelUpdated
new g_fwdUserReceiveXP
new g_fwdUserXPUpdated

public plugin_init()
{
    
register_plugin("OciXCrom's Rank System"PLUGIN_VERSION"OciXCrom")
    
register_cvar("CRXRankSystem"PLUGIN_VERSIONFCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)

    
#if defined USE_CSTRIKE
    
register_dictionary("RankSystem.txt")
    
#else
    
register_dictionary("RankSystemNoColors.txt")
    
#endif

    
register_event("DeathMsg""OnPlayerKilled""a")

    
register_clcmd("say /xplist",            "Cmd_XPList",      ADMIN_BAN)
    
register_clcmd("say_team /xplist",       "Cmd_XPList",      ADMIN_BAN)
    
register_concmd("crxranks_give_xp",      "Cmd_GiveXP",      ADMIN_RCON"<nick|#userid> <amount>")
    
register_concmd("crxranks_reset_xp",     "Cmd_ResetXP",     ADMIN_RCON"<nick|#userid>")
    
register_srvcmd("crxranks_update_mysql""Cmd_UpdateMySQL")

    if(
g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] || g_eSettings[LEVELDN_SCREEN_FADE_ENABLED])
    {
        
g_iScreenFade get_user_msgid("ScreenFade")
    }

    
g_fwdUserLevelUpdated CreateMultiForward("crxranks_user_level_updated"ET_IGNOREFP_CELLFP_CELLFP_CELL)
    
g_fwdUserReceiveXP    CreateMultiForward("crxranks_user_receive_xp",    ET_STOP,   FP_CELLFP_CELLFP_CELL)
    
g_fwdUserXPUpdated    CreateMultiForward("crxranks_user_xp_updated",    ET_IGNOREFP_CELLFP_CELLFP_CELL)

    if(
g_eSettings[USE_MYSQL])
    {
        
g_iSqlTuple SQL_MakeDbTuple(g_eSettings[SQL_HOST], g_eSettings[SQL_USER], g_eSettings[SQL_PASSWORD], g_eSettings[SQL_DATABASE])

        new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

        if(
iSqlConnection == Empty_Handle)
        {
            
log_amx(g_szSqlError)
            
switch_to_nvault()
            goto @
AFTER_MYSQL
        
}

        new 
Handle:iQueries SQL_PrepareQuery(iSqlConnection,\
        
"CREATE TABLE IF NOT EXISTS `%s` (`Player` VARCHAR(%i) NOT NULL, `XP` INT(%i) NOT NULL, `Level` INT(%i) NOT NULL,\
        `Next XP` INT(%i) NOT NULL, `Rank` VARCHAR(%i) NOT NULL, `Next Rank` VARCHAR(%i) NOT NULL, PRIMARY KEY(Player));"
,\
        
g_eSettings[SQL_TABLE], MAX_SQL_PLAYER_LENGTHCRXRANKS_MAX_XP_LENGTHCRXRANKS_MAX_XP_LENGTHCRXRANKS_MAX_XP_LENGTH,\
        
MAX_SQL_RANK_LENGTHMAX_SQL_RANK_LENGTH)

        if(!
SQL_Execute(iQueries))
        {
            
SQL_QueryError(iQueriesg_szSqlErrorcharsmax(g_szSqlError))
            
log_amx(g_szSqlError)
            
switch_to_nvault()
            goto @
AFTER_MYSQL
        
}

        
SQL_FreeHandle(iQueries)
        
SQL_FreeHandle(iSqlConnection)
    }

    @
AFTER_MYSQL:

    if(!
g_eSettings[USE_MYSQL])
    {
        
g_iVault nvault_open(g_eSettings[VAULT_NAME])
    }
}

public 
plugin_precache()
{
    
g_aLevels ArrayCreate(16)
    
ArrayPushCell(g_aLevels0)

    
g_aRankNames ArrayCreate(32)
    
ArrayPushString(g_aRankNames"")

    
g_tSettings TrieCreate()
    
g_tXPRewards TrieCreate()
    
g_tXPRewardsVIP TrieCreate()

    
ReadFile()
}

public 
plugin_end()
{
    
ArrayDestroy(g_aLevels)
    
ArrayDestroy(g_aRankNames)
    
TrieDestroy(g_tSettings)
    
TrieDestroy(g_tXPRewards)
    
TrieDestroy(g_tXPRewardsVIP)
    
DestroyForward(g_fwdUserLevelUpdated)

    if(!
g_eSettings[USE_MYSQL])
    {
        
nvault_close(g_iVault)
    }
}

ReadFile()
{
    new 
szFilename[256]
    
get_configsdir(szFilenamecharsmax(szFilename))
    
add(szFilenamecharsmax(szFilename), "/RankSystem.ini")

    new 
iFilePointer fopen(szFilename"rt")

    if(
iFilePointer)
    {
        new 
szData[CRXRANKS_MAX_HUDINFO_LENGTH MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], szMap[MAX_NAME_LENGTH], szKey[MAX_NAME_LENGTH]
        new 
szTemp[4][5], bool:bRead trueiiSizeiSection SECTION_NONE
        get_mapname
(szMapcharsmax(szMap))

        while(!
feof(iFilePointer))
        {
            
fgets(iFilePointerszDatacharsmax(szData))
            
trim(szData)

            switch(
szData[0])
            {
                case 
EOS'#'';': continue
                case 
'-':
                {
                    
iSize strlen(szData)

                    if(
szData[iSize 1] == '-')
                    {
                        
szData[0] = ' '
                        
szData[iSize 1] = ' '
                        
trim(szData)

                        if(
contain(szData"*") != -1)
                        {
                            
strtok(szDataszKeycharsmax(szKey), szValuecharsmax(szValue), '*')
                            
copy(szValuestrlen(szKey), szMap)
                            
bRead equal(szValueszKey) ? true false
                        
}
                        else
                        {
                            static const 
szAll[] = "#all"
                            
bRead equal(szDataszAll) || equali(szDataszMap)
                        }
                    }
                    else continue
                }
                case 
'[':
                {
                    
iSize strlen(szData)

                    if(
szData[iSize 1] == ']')
                    {
                        switch(
szData[1])
                        {
                            case 
'S''s'iSection SECTION_SETTINGS
                            
case 'R''r'iSection SECTION_RANKS
                            
case 'X''x'iSection SECTION_XP_REWARDS
                            
default: iSection SECTION_NONE
                        
}
                    }
                    else continue
                }
                default:
                {
                    if(!
bRead || iSection == SECTION_NONE)
                    {
                        continue
                    }

                    
strtok(szDataszKeycharsmax(szKey), szValuecharsmax(szValue), '=')
                    
trim(szKey); trim(szValue)

                    if(!
szValue[0])
                    {
                        continue
                    }

                    switch(
iSection)
                    {
                        case 
SECTION_SETTINGS:
                        {
                            
TrieSetString(g_tSettingsszKeyszValue)

                            if(
equal(szKey"CHAT_PREFIX"))
                            {
                                
#if defined USE_CSTRIKE
                                
CC_SetPrefix(szValue)
                                
#else
                                
copy(CC_PREFIXcharsmax(CC_PREFIX), szValue)
                                
#endif
                            
}
                            else if(
equal(szKey"SAVE_TYPE"))
                            {
                                
g_eSettings[SAVE_TYPE] = clamp(str_to_num(szValue), SAVE_NICKNAMESAVE_STEAMID)
                            }
                            else if(
equal(szKey"USE_MYSQL"))
                            {
                                
g_eSettings[USE_MYSQL] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"SQL_HOST"))
                            {
                                
copy(g_eSettings[SQL_HOST], charsmax(g_eSettings[SQL_HOST]), szValue)
                            }
                            else if(
equal(szKey"SQL_USER"))
                            {
                                
copy(g_eSettings[SQL_USER], charsmax(g_eSettings[SQL_USER]), szValue)
                            }
                            else if(
equal(szKey"SQL_PASSWORD"))
                            {
                                
copy(g_eSettings[SQL_PASSWORD], charsmax(g_eSettings[SQL_PASSWORD]), szValue)
                            }
                            else if(
equal(szKey"SQL_DATABASE"))
                            {
                                
copy(g_eSettings[SQL_DATABASE], charsmax(g_eSettings[SQL_DATABASE]), szValue)
                            }
                            else if(
equal(szKey"SQL_TABLE"))
                            {
                                
copy(g_eSettings[SQL_TABLE], charsmax(g_eSettings[SQL_TABLE]), szValue)
                            }
                            else if(
equal(szKey"XP_COMMANDS"))
                            {
                                while(
szValue[0] != && strtok(szValueszKeycharsmax(szKey), szValuecharsmax(szValue), ','))
                                {
                                    
trim(szKey); trim(szValue)
                                    
register_clcmd(szKey"Cmd_XP")
                                }
                            }
                            else if(
equal(szKey"LEVELUP_MESSAGE_TYPE"))
                            {
                                
g_eSettings[LEVELUP_MESSAGE_TYPE] = clamp(str_to_num(szValue), 02)
                            }
                            else if(
equal(szKey"LEVELUP_SOUND"))
                            {
                                
copy(g_eSettings[LEVELUP_SOUND], charsmax(g_eSettings[LEVELUP_SOUND]), szValue)

                                if(
szValue[0])
                                {
                                    
precache_sound(szValue)
                                }
                            }
                            else if(
equal(szKey"LEVELUP_SCREEN_FADE_ENABLED"))
                            {
                                
g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"LEVELUP_SCREEN_FADE_COLOR"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]), szTemp[3], charsmax(szTemp[]))

                                for(
04i++)
                                {
                                    
g_eSettings[LEVELUP_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"LEVELDN_SOUND"))
                            {
                                
copy(g_eSettings[LEVELDN_SOUND], charsmax(g_eSettings[LEVELDN_SOUND]), szValue)

                                if(
szValue[0])
                                {
                                    
precache_sound(szValue)
                                }
                            }
                            else if(
equal(szKey"LEVELDN_SCREEN_FADE_ENABLED"))
                            {
                                
g_eSettings[LEVELDN_SCREEN_FADE_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"LEVELDN_SCREEN_FADE_COLOR"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]), szTemp[3], charsmax(szTemp[]))

                                for(
04i++)
                                {
                                    
g_eSettings[LEVELDN_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"FINAL_LEVEL_FLAGS"))
                            {
                                
copy(g_eSettings[FINAL_LEVEL_FLAGS], charsmax(g_eSettings[FINAL_LEVEL_FLAGS]), szValue)
                                
g_eSettings[FINAL_LEVEL_FLAGS_BIT] = read_flags(szValue)
                                
g_iFlagZ read_flags("z")
                            }
                            else if(
equal(szKey"VIP_FLAGS"))
                            {
                                
copy(g_eSettings[VIP_FLAGS], charsmax(g_eSettings[VIP_FLAGS]), szValue)
                                
g_eSettings[VIP_FLAGS_BIT] = read_flags(szValue)
                            }
                            else if(
equal(szKey"VAULT_NAME"))
                            {
                                
copy(g_eSettings[VAULT_NAME], charsmax(g_eSettings[VAULT_NAME]), szValue)
                            }
                            else if(
equal(szKey"TEAM_LOCK"))
                            {
                                
g_eSettings[TEAM_LOCK] = str_to_num(szValue)
                            }
                            else if(
equal(szKey"MINIMUM_PLAYERS"))
                            {
                                
g_eSettings[MINIMUM_PLAYERS] = clamp(str_to_num(szValue), 032)
                            }
                            else if(
equal(szKey"IGNORE_BOTS"))
                            {
                                
g_eSettings[IGNORE_BOTS] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"USE_COMBINED_EVENTS"))
                            {
                                
g_eSettings[USE_COMBINED_EVENTS] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"NOTIFY_ON_KILL"))
                            {
                                
g_eSettings[NOTIFY_ON_KILL] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_ENABLED"))
                            {
                                
g_eSettings[HUDINFO_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_ALIVE_ONLY"))
                            {
                                
g_eSettings[HUDINFO_ALIVE_ONLY] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_TEAM_LOCK"))
                            {
                                
g_eSettings[HUDINFO_TEAM_LOCK] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_OTHER_PLAYERS"))
                            {
                                
g_eSettings[HUDINFO_OTHER_PLAYERS] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_COLOR"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

                                for(
03i++)
                                {
                                    
g_eSettings[HUDINFO_COLOR][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"HUDINFO_POSITION"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

                                for(
02i++)
                                {
                                    
g_eSettings[HUDINFO_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.01.0)
                                }
                            }
                            else if(
equal(szKey"HUDINFO_USE_DHUD"))
                            {
                                
g_eSettings[HUDINFO_USE_DHUD] = _:clamp(str_to_num(szValue), falsetrue)

                                if(!
g_eSettings[HUDINFO_USE_DHUD])
                                {
                                    
g_iObject[OBJ_HUDINFO] = CreateHudSyncObj()
                                }
                            }
                            else if(
equal(szKey"HUDINFO_FORMAT"))
                            {
                                
copy(g_eSettings[HUDINFO_FORMAT], charsmax(g_eSettings[HUDINFO_FORMAT]), szValue)
                            }
                            else if(
equal(szKey"HUDINFO_FORMAT_FINAL"))
                            {
                                
copy(g_eSettings[HUDINFO_FORMAT_FINAL], charsmax(g_eSettings[HUDINFO_FORMAT_FINAL]), szValue)
                            }
                            else if(
equal(szKey"HUDINFO_INVALID_TEXT"))
                            {
                                
copy(g_eSettings[HUDINFO_INVALID_TEXT], charsmax(g_eSettings[HUDINFO_INVALID_TEXT]), szValue)
                            }
                            else if(
equal(szKey"XP_NOTIFIER_ENABLED"))
                            {
                                
g_eSettings[XP_NOTIFIER_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"XP_NOTIFIER_COLOR_GET"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

                                for(
03i++)
                                {
                                    
g_eSettings[XP_NOTIFIER_COLOR_GET][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"XP_NOTIFIER_COLOR_LOSE"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

                                for(
03i++)
                                {
                                    
g_eSettings[XP_NOTIFIER_COLOR_LOSE][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"XP_NOTIFIER_POSITION"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

                                for(
02i++)
                                {
                                    
g_eSettings[XP_NOTIFIER_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.01.0)
                                }
                            }
                            else if(
equal(szKey"XP_NOTIFIER_DURATION"))
                            {
                                
g_eSettings[XP_NOTIFIER_DURATION] = _:floatclamp(str_to_float(szValue), 0.0float(cellmax))
                            }
                            else if(
equal(szKey"XP_NOTIFIER_USE_DHUD"))
                            {
                                
g_eSettings[XP_NOTIFIER_USE_DHUD] = _:clamp(str_to_num(szValue), falsetrue)

                                if(!
g_eSettings[XP_NOTIFIER_USE_DHUD])
                                {
                                    
g_iObject[OBJ_XP_NOTIFIER] = CreateHudSyncObj()
                                }
                            }
                        }
                        case 
SECTION_RANKS:
                        {
                            
ArrayPushCell(g_aLevelsclamp(str_to_num(szValue), 0))
                            
ArrayPushString(g_aRankNamesszKey)
                            
g_iMaxLevels++
                        }
                        case 
SECTION_XP_REWARDS:
                        {
                            static 
szReward[2][16]
                            
szReward[1][0] = EOS

                            parse
(szValueszReward[0], charsmax(szReward[]), szReward[1], charsmax(szReward[]))
                            
TrieSetCell(g_tXPRewardsszKeystr_to_num(szReward[0]))

                            if(
szReward[1][0])
                            {
                                
TrieSetCell(g_tXPRewardsVIPszKeystr_to_num(szReward[1]))
                            }
                        }
                    }
                }
            }
        }

        
num_to_str(g_iMaxLevelsg_szMaxLevelscharsmax(g_szMaxLevels))
        
fclose(iFilePointer)
    }
}

public 
client_connect(id)
{
    
reset_player_stats(id)

    new 
szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH]
    
get_user_saveinfo(idszInfocharsmax(szInfo))
    
save_or_load(idszInfoSL_LOAD_DATA)

    
g_ePlayerData[id][IsBot] = is_user_bot(id) != 0
    set_task
(DELAY_ON_CONNECT"update_vip_status"id)

    if(
g_eSettings[HUDINFO_ENABLED])
    {
        
set_task(HUD_REFRESH_FREQ"DisplayHUD"id TASK_HUD, .flags "b")
    }
}

public 
client_disconnected(id)
{
    new 
szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH]
    
get_user_saveinfo(idszInfocharsmax(szInfo))
    
save_or_load(idszInfoSL_SAVE_DATA)
    
remove_task(id TASK_HUD)
}

public 
client_infochanged(id)
{
    if(!
is_user_connected(id))
    {
        return
    }

    static const 
szKey[] = "name"
    
static szNewName[MAX_NAME_LENGTH], szOldName[MAX_NAME_LENGTH]
    
get_user_info(idszKeyszNewNamecharsmax(szNewName))
    
get_user_name(idszOldNamecharsmax(szOldName))

    if(!
equal(szNewNameszOldName))
    {
        if(
g_eSettings[SAVE_TYPE] == SAVE_NICKNAME)
        {
            
save_or_load(idszOldNameSL_SAVE_DATA)

            if(
g_eSettings[USE_MYSQL])
            {
                
reset_player_stats(id)
                
set_task(DELAY_ON_CHANGE"load_after_change"id)
            }
            else
            {
                
save_or_load(idszNewNameSL_LOAD_DATA)
                
update_hudinfo(id)
            }
        }

        
set_task(DELAY_ON_CHANGE"update_vip_status"id)
    }
}

public 
load_after_change(id)
{
    static 
szName[MAX_NAME_LENGTH]
    
get_user_name(idszNamecharsmax(szName))
    
save_or_load(idszNameSL_LOAD_DATA)
    
update_hudinfo(id)
}

public 
DisplayHUD(id)
{
    
id -= TASK_HUD

    
static iTarget
    iTarget 
id

    
if(!is_user_alive(id))
    {
        if(
g_eSettings[HUDINFO_ALIVE_ONLY])
        {
            return
        }

        if(
g_eSettings[HUDINFO_OTHER_PLAYERS])
        {
            
iTarget pev(idpev_iuser2)
        }
    }

    if(!
iTarget)
    {
        return
    }

    if(
g_eSettings[TEAM_LOCK] && g_eSettings[HUDINFO_TEAM_LOCK] && get_user_team(iTarget) != g_eSettings[TEAM_LOCK])
    {
        return
    }

    if(
g_eSettings[HUDINFO_USE_DHUD])
    {
        
set_dhudmessage(HUDINFO_PARAMS)
        
show_dhudmessage(idg_ePlayerData[iTarget][HUDInfo])
    }
    else
    {
        
set_hudmessage(HUDINFO_PARAMS)
        
ShowSyncHudMsg(idg_iObject[OBJ_HUDINFO], g_ePlayerData[iTarget][HUDInfo])
    }
}

#if defined USE_CSTRIKE
public bomb_planted(id)
{
    
give_user_xp(idget_xp_reward(idXPREWARD_BOMB_PLANTED), CRXRANKS_XPS_REWARD)
}

public 
bomb_defused(id)
{
    
give_user_xp(idget_xp_reward(idXPREWARD_BOMB_DEFUSED), CRXRANKS_XPS_REWARD)
}

public 
bomb_explode(id)
{
    
give_user_xp(idget_xp_reward(idXPREWARD_BOMB_EXPLODED), CRXRANKS_XPS_REWARD)
}
#endif

public Cmd_XP(id)
{
    if(
g_ePlayerData[id][Level] == g_iMaxLevels)
    {
        
send_chat_message(idfalse"%L"id"CRXRANKS_RANKINFO_FINAL"g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
    }
    else
    {
        
send_chat_message(idfalse"%L"id"CRXRANKS_RANKINFO_NORMAL"g_ePlayerData[id][XP], g_ePlayerData[id][NextXP],\
        
g_ePlayerData[id][Level], g_ePlayerData[id][Rank], g_ePlayerData[id][NextRank])
    }

    return 
PLUGIN_HANDLED
}

public 
Cmd_XPList(idiLeveliCid)
{
    if(!
cmd_access(idiLeveliCid1))
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szTitle[128]
    
formatex(szTitlecharsmax(szTitle), "%L"id"CRXRANKS_MENU_TITLE")

    new 
iPlayers[32], iPnumiMenu menu_create(szTitle"XPList_Handler")
    
get_players(iPlayersiPnum); SortCustom1D(iPlayersiPnum"sort_players_by_xp")

    for(new 
szItem[128], szName[32], iPlayeriiPnumi++)
    {
        
iPlayer iPlayers[i]
        
get_user_name(iPlayerszNamecharsmax(szName))
        
formatex(szItemcharsmax(szItem), "%L"id"CRXRANKS_ITEM_FORMAT"g_ePlayerData[iPlayer][XP], szNameg_ePlayerData[iPlayer][Level], g_ePlayerData[iPlayer][Rank])
        
menu_additem(iMenuszItem)
    }

    
menu_display(idiMenu)
    return 
PLUGIN_HANDLED
}

public 
XPList_Handler(idiMenuiItem)
{
    
menu_destroy(iMenu)
    return 
PLUGIN_HANDLED
}

public 
Cmd_GiveXP(idiLeveliCid)
{
    if(!
cmd_access(idiLeveliCid3))
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szPlayer[MAX_NAME_LENGTH]
    
read_argv(1szPlayercharsmax(szPlayer))

    new 
iPlayer cmd_target(idszPlayer0)

    if(!
iPlayer)
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szName[2][MAX_NAME_LENGTH], szAmount[CRXRANKS_MAX_XP_LENGTH]
    
read_argv(2szAmountcharsmax(szAmount))
    
get_user_name(idszName[0], charsmax(szName[]))
    
get_user_name(iPlayerszName[1], charsmax(szName[]))

    new 
szKey[32], iXP str_to_num(szAmount)
    
give_user_xp(iPlayeriXPCRXRANKS_XPS_ADMIN)

    if(
iXP >= 0)
    {
        
copy(szKeycharsmax(szKey), "CRXRANKS_GIVE_XP")
    }
    else
    {
        
copy(szKeycharsmax(szKey), "CRXRANKS_TAKE_XP")
        
iXP *= -1
    
}

    
send_chat_message(0true"%L"idszKeyszName[0], iXPszName[1])
    return 
PLUGIN_HANDLED
}

public 
Cmd_ResetXP(idiLeveliCid)
{
    if(!
cmd_access(idiLeveliCid2))
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szPlayer[MAX_NAME_LENGTH]
    
read_argv(1szPlayercharsmax(szPlayer))

    new 
iPlayer cmd_target(idszPlayerCMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF)

    if(!
iPlayer)
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szName[2][MAX_NAME_LENGTH]
    
get_user_name(idszName[0], charsmax(szName[]))
    
get_user_name(iPlayerszName[1], charsmax(szName[]))

    
g_ePlayerData[iPlayer][XP] = 0
    check_level
(iPlayertrue)
    
send_chat_message(0true"%L"id"CRXRANKS_RESET_XP"szName[0], szName[1])

    return 
PLUGIN_HANDLED
}

// This command is here because the update from v3.0 to v3.1 changed the way data is stored in MySQL.
// Because of that, a new table is required and this command is here to transfer the data from the old one.
// The command will be removed in future versions, so I decided not to translate the strings used in it.
public Cmd_UpdateMySQL()
{
    static 
bUsed

    
if(bUsed)
    {
        
server_print("The MySQL table has already been updated to version v3.1. There's no point in doing this again.")
        return 
PLUGIN_HANDLED
    
}

    if(!
g_eSettings[USE_MYSQL])
    {
        
server_print("The plugin isn't using MySQL at the moment. Please enable the feature before using this command.")
        return 
PLUGIN_HANDLED
    
}

    new 
szTable[MAX_NAME_LENGTH]
    
read_argv(1szTablecharsmax(szTable))

    if(!
szTable[0])
    {
        
server_print("Plese provide the name of the previous table in order to transfer data to the current one.")
        return 
PLUGIN_HANDLED
    
}

    new 
szQuery[MAX_NAME_LENGTH 2]
    
formatex(szQuerycharsmax(szQuery), "SELECT * FROM `%s`;"szTable)
    
SQL_ThreadQuery(g_iSqlTuple"QueryUpdateMySQL"szQuery)

    
bUsed true
    
return PLUGIN_HANDLED
}

public 
QueryUpdateMySQL(iFailStateHandle:iQueryszError[], iErrorCode)
{
    if(
iFailState == TQUERY_CONNECT_FAILED || iFailState == TQUERY_QUERY_FAILED)
    {
        
server_print(szError)
        return
    }

    new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

    if(
iSqlConnection == Empty_Handle)
    {
        
server_print(g_szSqlError)
        return
    }

    new 
Handle:iQuery2szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szInfo[MAX_SQL_PLAYER_LENGTH], iCounteriPlayeriXP
    
new szColumnPlayer SQL_FieldNameToNum(iQuery"User")
    new 
szColumnXP SQL_FieldNameToNum(iQuery"XP")

    while(
SQL_MoreResults(iQuery))
    {
        
SQL_ReadResult(iQueryszColumnPlayerszInfocharsmax(szInfo))
        
SQL_QuoteString(iSqlConnectionszPlayercharsmax(szPlayer), szInfo)
        
iQuery2 SQL_PrepareQuery(iSqlConnection"SELECT * FROM %s WHERE Player = '%s';"g_eSettings[SQL_TABLE], szPlayer)

        if(!
SQL_Execute(iQuery2))
        {
            
SQL_QueryError(iQuery2g_szSqlErrorcharsmax(g_szSqlError))
            
server_print(g_szSqlError)
            return
        }

        
iXP SQL_ReadResult(iQueryszColumnXP)

        if(
SQL_NumResults(iQuery2) > 0)
        {
            
formatex(szQuerycharsmax(szQuery), "UPDATE `%s` SET `XP`='%i' WHERE `Player`='%s';"g_eSettings[SQL_TABLE], iXPszPlayer)
        }
        else
        {
            
formatex(szQuerycharsmax(szQuery), "INSERT INTO %s (`Player`,`XP`,`Level`,`Next XP`,`Rank`,`Next Rank`) VALUES ('%s','%i','1','0','n/a','n/a');"g_eSettings[SQL_TABLE], szPlayeriXP)
        }

        switch(
g_eSettings[SAVE_TYPE])
        {
            case 
CRXRANKS_ST_NICKNAMEiPlayer find_player("a"szInfo)
            case 
CRXRANKS_ST_STEAMID:  iPlayer find_player("c"szInfo)
            case 
CRXRANKS_ST_IP:       iPlayer find_player("d"szInfo)
        }

        if(
iPlayer)
        {
            
g_ePlayerData[iPlayer][XP] = iXP
            check_level
(iPlayertrue)
        }

        
SQL_ThreadQuery(g_iSqlTuple"QueryHandler"szQuery)
        
SQL_NextRow(iQuery)
        
iCounter++
    }

    
SQL_FreeHandle(iQuery2)
    
SQL_FreeHandle(iSqlConnection)
}

public 
OnPlayerKilled()
{
    new 
iAttacker read_data(1), iVictim read_data(2)

    if(!
is_user_connected(iAttacker) || !is_user_connected(iVictim))
    {
        return
    }

    new 
iRewardiTemp

    
if(iAttacker == iVictim)
    {
        
iTemp get_xp_reward(iAttackerXPREWARD_SUICIDE)
        
iReward += iTemp

        
if(should_skip(iTemp))
        {
            goto @
GIVE_REWARD
        
}
    }
    else if(
get_user_team(iAttacker) == get_user_team(iVictim))
    {
        
iTemp get_xp_reward(iAttackerXPREWARD_TEAMKILL)
        
iReward += iTemp

        
if(should_skip(iTemp))
        {
            goto @
GIVE_REWARD
        
}
    }
    else
    {
        new 
szWeapon[16]
        
read_data(4szWeaponcharsmax(szWeapon))

        
iTemp get_xp_reward(iAttackerszWeapon)
        
iReward += iTemp

        
if(should_skip(iTemp))
        {
            goto @
GIVE_REWARD
        
}

        if(
read_data(3))
        {
            
iTemp get_xp_reward(iAttackerXPREWARD_HEADSHOT)
            
iReward += iTemp

            
if(should_skip(iTemp))
            {
                goto @
GIVE_REWARD
            
}
        }

        
iReward += get_xp_reward(iAttackerXPREWARD_KILL)
    }

    @
GIVE_REWARD:
    new 
iXP give_user_xp(iAttackeriRewardCRXRANKS_XPS_REWARD)

    if(
g_eSettings[NOTIFY_ON_KILL] && iXP != 0)
    {
        if(
iAttacker == iVictim)
        {
            
CC_SendMessage(iAttacker"%L"iAttacker"CRXRANKS_NOTIFY_SUICIDE"abs(iXP))
        }
        else
        {
            new 
szName[MAX_NAME_LENGTH]
            
get_user_name(iVictimszNamecharsmax(szName))
            
CC_SendMessage(iAttacker"%L"iAttackeriXP >= "CRXRANKS_NOTIFY_KILL_GET" "CRXRANKS_NOTIFY_KILL_LOSE"abs(iXP), szName)
        }
    }
}

public 
sort_players_by_xp(id1id2)
{
    if(
g_ePlayerData[id1][XP] > g_ePlayerData[id2][XP])
    {
        return -
1
    
}
    else if(
g_ePlayerData[id1][XP] < g_ePlayerData[id2][XP])
    {
        return 
1
    
}

    return 
0
}

public 
QueryHandler(iFailStateHandle:iQueryszError[], iErrorCode)
{
    switch(
iFailState)
    {
        case 
TQUERY_CONNECT_FAILEDlog_amx("[SQL Error] Connection failed (%i): %s"iErrorCodeszError)
        case 
TQUERY_QUERY_FAILED:   log_amx("[SQL Error] Query failed (%i): %s"iErrorCodeszError)
    }
}

save_or_load(const id, const szInfo[], const iType)
{
    if(!
szInfo[0])
    {
        return
    }

    switch(
iType)
    {
        case 
SL_SAVE_DATA:
        {
            if(
g_eSettings[USE_MYSQL])
            {
                static 
szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szRank[MAX_SQL_RANK_LENGTH], szNextRank[MAX_SQL_RANK_LENGTH]
                new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

                
SQL_QuoteString(iSqlConnectionszPlayercharsmax(szPlayer), szInfo)
                
SQL_QuoteString(iSqlConnectionszRankcharsmax(szRank), g_ePlayerData[id][Rank])
                
SQL_QuoteString(iSqlConnectionszNextRankcharsmax(szNextRank), g_ePlayerData[id][NextRank])

                
formatex(szQuerycharsmax(szQuery), "UPDATE `%s` SET `XP`='%i',`Level`='%i',`Next XP`='%i',`Rank`='%s',`Next Rank`='%s' WHERE `Player`='%s';",\
                
g_eSettings[SQL_TABLE], g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][NextXP], szRankszNextRankszPlayer)
                
SQL_ThreadQuery(g_iSqlTuple"QueryHandler"szQuery)
            }
            else
            {
                static 
szData[CRXRANKS_MAX_XP_LENGTH]
                
num_to_str(g_ePlayerData[id][XP], szDatacharsmax(szData))
                
nvault_set(g_iVaultszInfoszData)
            }
        }
        case 
SL_LOAD_DATA:
        {
            if(
g_eSettings[USE_MYSQL])
            {
                static 
szPlayer[MAX_SQL_PLAYER_LENGTH]
                new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))
                
SQL_QuoteString(iSqlConnectionszPlayercharsmax(szPlayer), szInfo)

                if(
iSqlConnection == Empty_Handle)
                {
                    
log_amx(g_szSqlError)
                    return
                }

                new 
Handle:iQuery SQL_PrepareQuery(iSqlConnection"SELECT * FROM %s WHERE Player = '%s';"g_eSettings[SQL_TABLE], szPlayer)

                if(!
SQL_Execute(iQuery))
                {
                    
SQL_QueryError(iQueryg_szSqlErrorcharsmax(g_szSqlError))
                    
log_amx(g_szSqlError)
                    return
                }

                
prepare_player(idszPlayerSQL_NumResults(iQuery) > false true)
                
SQL_FreeHandle(iQuery)
                
SQL_FreeHandle(iSqlConnection)
            }
            else
            {
                static 
iData
                iData 
nvault_get(g_iVaultszInfo)
                
g_ePlayerData[id][XP] = iData clamp(iData0) : 0
                check_level
(idfalse)
            }
        }
    }
}

prepare_player(id, const szPlayer[], bool:bNewPlayer)
{
    new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

    if(
iSqlConnection == Empty_Handle)
    {
        
log_amx(g_szSqlError)
        return
    }

    static 
szQuery[MAX_QUERY_LENGTH]

    if(
bNewPlayer)
    {
        
formatex(szQuerycharsmax(szQuery), "INSERT INTO %s (`Player`,`XP`,`Level`,`Next XP`,`Rank`,`Next Rank`) VALUES ('%s','0','1','0','n/a','n/a');"g_eSettings[SQL_TABLE], szPlayer)
    }
    else
    {
        
formatex(szQuerycharsmax(szQuery), "SELECT XP FROM %s WHERE Player = '%s';"g_eSettings[SQL_TABLE], szPlayer)
    }

    new 
Handle:iQuery SQL_PrepareQuery(iSqlConnectionszQuery)

    if(!
SQL_Execute(iQuery))
    {
        
SQL_QueryError(iQueryg_szSqlErrorcharsmax(g_szSqlError))
        
log_amx(g_szSqlError)
    }

    if(!
bNewPlayer)
    {
        if(
SQL_NumResults(iQuery) > 0)
        {
            
g_ePlayerData[id][XP] = SQL_ReadResult(iQuery0)
        }
    }

    
check_level(idfalse)

    
SQL_FreeHandle(iQuery)
    
SQL_FreeHandle(iSqlConnection)
}

get_xp_reward(const id, const szKey[])
{
    static 
iReward

    
if(g_ePlayerData[id][IsVIP])
    {
        if(
TrieKeyExists(g_tXPRewardsVIPszKey))
        {
            
TrieGetCell(g_tXPRewardsVIPszKeyiReward)
            return 
iReward
        
}
    }

    if(
TrieKeyExists(g_tXPRewardsszKey))
    {
        
TrieGetCell(g_tXPRewardsszKeyiReward)
        return 
iReward
    
}

    return 
0
}

give_user_xp(const idiXPCRXRanks_XPSources:iSource CRXRANKS_XPS_PLUGIN)
{
    if(!
iXP)
    {
        return 
0
    
}

    if(
g_eSettings[IGNORE_BOTS] && g_ePlayerData[id][IsBot])
    {
        return 
0
    
}

    if(
iSource == CRXRANKS_XPS_REWARD)
    {
        if(
g_eSettings[MINIMUM_PLAYERS] && get_playersnum() < g_eSettings[MINIMUM_PLAYERS])
        {
            return 
0
        
}

        if(
g_eSettings[TEAM_LOCK] && get_user_team(id) != g_eSettings[TEAM_LOCK])
        {
            return 
0
        
}
    }

    static 
iReturn
    ExecuteForward
(g_fwdUserReceiveXPiReturnidiXPiSource)

    switch(
iReturn)
    {
        case 
CRXRANKS_HANDLED: return 0
        
case CRXRANKS_CONTINUE: { }
        default:
        {
            if(
iReturn != 0)
            {
                
iXP iReturn
            
}
        }
    }

    
g_ePlayerData[id][XP] += iXP

    
if(g_ePlayerData[id][XP] < 0)
    {
        
g_ePlayerData[id][XP] = 0
    
}

    
check_level(idtrue)
    
ExecuteForward(g_fwdUserXPUpdatediReturnidg_ePlayerData[id][XP], iSource)

    if(
g_eSettings[XP_NOTIFIER_ENABLED])
    {
        static 
szKey[32], bool:bPositive
        bPositive 
iXP >= 0

        copy
(szKeycharsmax(szKey), bPositive "CRXRANKS_XP_NOTIFIER_GET" "CRXRANKS_XP_NOTIFIER_LOSE")

        if(
g_eSettings[XP_NOTIFIER_USE_DHUD])
        {
            if(
bPositive)
            {
                
set_dhudmessage(XP_NOTIFIER_PARAMS_GET)
            }
            else
            {
                
set_dhudmessage(XP_NOTIFIER_PARAMS_LOSE)
            }

            
show_dhudmessage(id"%L"idszKeyabs(iXP))
        }
        else
        {
            if(
bPositive)
            {
                
set_hudmessage(XP_NOTIFIER_PARAMS_GET)
            }
            else
            {
                
set_hudmessage(XP_NOTIFIER_PARAMS_LOSE)
            }

            
ShowSyncHudMsg(idg_iObject[OBJ_XP_NOTIFIER], "%L"idszKeyabs(iXP))
        }
    }

    return 
iXP
}

get_user_saveinfo(const idszInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH], const iLen)
{
    switch(
g_eSettings[SAVE_TYPE])
    {
        case 
SAVE_NICKNAME:    get_user_name(idszInfoiLen)
        case 
SAVE_IPget_user_ip(idszInfoiLen1)
        case 
SAVE_STEAMIDget_user_authid(idszInfoiLen)
    }
}

reset_player_stats(const id)
{
    
g_ePlayerData[id][XP] = 0
    g_ePlayerData
[id][Level] = 0
    g_ePlayerData
[id][NextXP] = 0
    g_ePlayerData
[id][Rank][0] = EOS
    g_ePlayerData
[id][NextRank][0] = EOS
    g_ePlayerData
[id][HUDInfo][0] = EOS
    g_ePlayerData
[id][IsOnFinalLevel] = false
    g_ePlayerData
[id][IsVIP] = false
    g_ePlayerData
[id][IsBot] = false
}

switch_to_nvault()
{
    if(
g_eSettings[USE_MYSQL])
    {
        
g_eSettings[USE_MYSQL] = false
        log_amx
("%L"LANG_SERVER"CRXRANKS_MYSQL_FAILED")
    }
}

bool:has_argument(const szMessage[], const szArg[])
{
    return 
contain(szMessageszArg) != -1
}

bool:should_skip(const iNum)
{
    return (
iNum != && !g_eSettings[USE_COMBINED_EVENTS])
}

send_chat_message(const id, const bool:bLog, const szInput[], any:...)
{
    static 
szMessage[192]
    
vformat(szMessagecharsmax(szMessage), szInput4)

    
#if defined USE_CSTRIKE
    
bLog CC_LogMessage(id_szMessage) : CC_SendMessage(idszMessage)
    
#else
    
format(szMessagecharsmax(szMessage), "%s %s"CC_PREFIXszMessage)
    
client_print(idprint_chatszMessage)

    if(
bLog)
    {
        
log_amx(szMessage)
    }
    
#endif
}

update_hudinfo(const id)
{
    if(!
g_eSettings[HUDINFO_ENABLED])
    {
        return
    }

    static 
szMessage[CRXRANKS_MAX_HUDINFO_LENGTH], szPlaceHolder[32], bool:bIsOnFinal

    bIsOnFinal 
g_ePlayerData[id][IsOnFinalLevel]
    
copy(szMessagecharsmax(szMessage), g_eSettings[bIsOnFinal HUDINFO_FORMAT_FINAL HUDINFO_FORMAT])

    if(
has_argument(szMessageARG_CURRENT_XP))
    {
        
num_to_str(g_ePlayerData[id][XP], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_CURRENT_XPszPlaceHolder)
    }

    if(
has_argument(szMessageARG_NEXT_XP))
    {
        
num_to_str(g_ePlayerData[id][NextXP], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NEXT_XPszPlaceHolder)
    }

    if(
has_argument(szMessageARG_XP_NEEDED))
    {
        
num_to_str(g_ePlayerData[id][NextXP] - g_ePlayerData[id][XP], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_XP_NEEDEDszPlaceHolder)
    }

    if(
has_argument(szMessageARG_LEVEL))
    {
        
num_to_str(g_ePlayerData[id][Level], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_LEVELszPlaceHolder)
    }

    if(
has_argument(szMessageARG_NEXT_LEVEL))
    {
        
num_to_str(g_ePlayerData[id][bIsOnFinal Level Level 1], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NEXT_LEVELszPlaceHolder)
    }

    
replace_string(szMessagecharsmax(szMessage), ARG_MAX_LEVELSg_szMaxLevels)

    if(
has_argument(szMessageARG_NAME))
    {
        
get_user_name(idszPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NAMEszPlaceHolder)
    }

    
replace_string(szMessagecharsmax(szMessage), ARG_RANKg_ePlayerData[id][Rank])
    
replace_string(szMessagecharsmax(szMessage), ARG_NEXT_RANKg_ePlayerData[id][NextRank])
    
replace_string(szMessagecharsmax(szMessage), ARG_LINE_BREAK"^n")
    
copy(g_ePlayerData[id][HUDInfo], charsmax(g_ePlayerData[][HUDInfo]), szMessage)
}

check_level(const id, const bool:bNotify)
{
    static 
iLeveli
    iLevel 
0

    
for(1g_iMaxLevels 1i++)
    {
        if(
g_ePlayerData[id][XP] >= ArrayGetCell(g_aLevelsi))
        {
            
iLevel++
        }
    }

    if(
iLevel != g_ePlayerData[id][Level])
    {
        static 
bool:bLevelUpiReturn
        bLevelUp 
iLevel g_ePlayerData[id][Level]
        
g_ePlayerData[id][Level] = iLevel
        ArrayGetString
(g_aRankNamesiLevelg_ePlayerData[id][Rank], charsmax(g_ePlayerData[][Rank]))

        if(
iLevel g_iMaxLevels)
        {
            
g_ePlayerData[id][IsOnFinalLevel] = false
            g_ePlayerData
[id][NextXP] = ArrayGetCell(g_aLevelsiLevel 1)
            
ArrayGetString(g_aRankNamesiLevel 1g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]))
        }
        else
        {
            
g_ePlayerData[id][IsOnFinalLevel] = true
            g_ePlayerData
[id][NextXP] = ArrayGetCell(g_aLevelsiLevel)
            
copy(g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]), g_eSettings[HUDINFO_INVALID_TEXT])

            if(
g_eSettings[FINAL_LEVEL_FLAGS])
            {
                
set_user_flags(idg_eSettings[FINAL_LEVEL_FLAGS_BIT])
                
remove_user_flags(idg_iFlagZ)
            }
        }

        
ExecuteForward(g_fwdUserLevelUpdatediReturnidiLevelbLevelUp)

        if(
bNotify && g_eSettings[LEVELUP_MESSAGE_TYPE])
        {
            static 
szMessage[128], szName[32], bool:bGlobalMsg
            get_user_name
(idszNamecharsmax(szName))
            
bGlobalMsg g_eSettings[LEVELUP_MESSAGE_TYPE] == 2

            formatex
(szMessagecharsmax(szMessage), "%L"bGlobalMsg LANG_PLAYER id,\
            
bLevelUp "CRXRANKS_LEVEL_REACHED" "CRXRANKS_LEVEL_LOST"szNameg_ePlayerData[id][Level], g_ePlayerData[id][Rank])
            
send_chat_message(bGlobalMsg idfalseszMessage)

            if(
bLevelUp && g_eSettings[LEVELUP_SOUND][0])
            {
                
emit_sound(idCHAN_AUTOg_eSettings[LEVELUP_SOUND], 1.0ATTN_NORM0PITCH_NORM)
            }
            else if(!
bLevelUp && g_eSettings[LEVELDN_SOUND][0])
            {
                
emit_sound(idCHAN_AUTOg_eSettings[LEVELDN_SOUND], 1.0ATTN_NORM0PITCH_NORM)
            }

            if(
g_eSettings[bLevelUp LEVELUP_SCREEN_FADE_ENABLED LEVELDN_SCREEN_FADE_ENABLED])
            {
                
message_begin(MSG_ONEg_iScreenFade, {000}, id)
                
write_short(1<<10)
                
write_short(1<<10)
                
write_short(0x0000)

                if(
bLevelUp)
                {
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][0]))
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][1]))
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][2]))
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][3]))
                }
                else
                {
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][0]))
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][1]))
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][2]))
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][3]))
                }

                
message_end()
            }
        }
    }

    
update_hudinfo(id)
}

public 
update_vip_status(id)
{
    if(
is_user_connected(id) && g_eSettings[VIP_FLAGS_BIT] != ADMIN_ALL)
    {
        
g_ePlayerData[id][IsVIP] = bool:((get_user_flags(id) & g_eSettings[VIP_FLAGS_BIT]) == g_eSettings[VIP_FLAGS_BIT])
    }
}

public 
plugin_natives()
{
    
register_library("crxranks")
    
register_native("crxranks_get_chat_prefix",         "_crxranks_get_chat_prefix")
    
register_native("crxranks_get_final_flags",         "_crxranks_get_final_flags")
    
register_native("crxranks_get_hudinfo_format",      "_crxranks_get_hudinfo_format")
    
register_native("crxranks_get_max_levels",          "_crxranks_get_max_levels")
    
register_native("crxranks_get_rank_by_level",       "_crxranks_get_rank_by_level")
    
register_native("crxranks_get_save_type",           "_crxranks_get_save_type")
    
register_native("crxranks_get_setting",             "_crxranks_get_setting")
    
register_native("crxranks_get_user_hudinfo",        "_crxranks_get_user_hudinfo")
    
register_native("crxranks_get_user_level",          "_crxranks_get_user_level")
    
register_native("crxranks_get_user_next_rank",      "_crxranks_get_user_next_rank")
    
register_native("crxranks_get_user_next_xp",        "_crxranks_get_user_next_xp")
    
register_native("crxranks_get_user_rank",           "_crxranks_get_user_rank")
    
register_native("crxranks_get_user_xp",             "_crxranks_get_user_xp")
    
register_native("crxranks_get_vault_name",          "_crxranks_get_vault_name")
    
register_native("crxranks_get_vip_flags",           "_crxranks_get_vip_flags")
    
register_native("crxranks_get_xp_for_level",        "_crxranks_get_xp_for_level")
    
register_native("crxranks_get_xp_reward",           "_crxranks_get_xp_reward")
    
register_native("crxranks_give_user_xp",            "_crxranks_give_user_xp")
    
register_native("crxranks_is_hi_using_dhud",        "_crxranks_is_hi_using_dhud")
    
register_native("crxranks_is_hud_enabled",          "_crxranks_is_hud_enabled")
    
register_native("crxranks_is_sfdn_enabled",         "_crxranks_is_sfdn_enabled")
    
register_native("crxranks_is_sfup_enabled",         "_crxranks_is_sfup_enabled")
    
register_native("crxranks_is_user_on_final",        "_crxranks_is_user_on_final")
    
register_native("crxranks_is_user_vip",             "_crxranks_is_user_vip")
    
register_native("crxranks_is_using_mysql",          "_crxranks_is_using_mysql")
    
register_native("crxranks_is_xpn_enabled",          "_crxranks_is_xpn_enabled")
    
register_native("crxranks_is_xpn_using_dhud",       "_crxranks_is_xpn_using_dhud")
    
register_native("crxranks_set_user_xp",             "_crxranks_set_user_xp")
    
register_native("crxranks_using_comb_events",       "_crxranks_using_comb_events")
}

public 
_crxranks_get_chat_prefix(iPluginiParams)
{
    
set_string(1CC_PREFIXget_param(2))
}

public 
_crxranks_get_final_flags(iPluginiParams)
{
    
set_string(1g_eSettings[FINAL_LEVEL_FLAGS], get_param(2))
    return 
g_eSettings[FINAL_LEVEL_FLAGS_BIT]
}

public 
_crxranks_get_hudinfo_format(iPluginiParams)
{
    
set_string(2g_eSettings[get_param(1) ? HUDINFO_FORMAT_FINAL HUDINFO_FORMAT], get_param(3))
}

public 
_crxranks_get_max_levels(iPluginiParams)
{
    return 
g_iMaxLevels
}

public 
_crxranks_get_rank_by_level(iPluginiParams)
{
    static 
iLevel
    iLevel 
get_param(1)

    if(
iLevel || iLevel g_iMaxLevels)
    {
        return 
0
    
}

    static 
szRank[CRXRANKS_MAX_RANK_LENGTH]
    
ArrayGetString(g_aRankNamesiLevelszRankcharsmax(szRank))
    
set_string(2szRankget_param(3))
    return 
1
}

public 
_crxranks_get_save_type(iPluginiParams)
{
    return 
g_eSettings[SAVE_TYPE]
}

public 
bool:_crxranks_get_setting(iPluginiParams)
{
    static 
szKey[MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], bool:bReturn
    get_string
(1szKeycharsmax(szKey))

    
bReturn TrieGetString(g_tSettingsszKeyszValuecharsmax(szValue))
    
set_string(2szValueget_param(3))
    return 
bReturn
}

public 
_crxranks_get_user_hudinfo(iPluginiParams)
{
    
set_string(2g_ePlayerData[get_param(1)][HUDInfo], get_param(3))
}

public 
_crxranks_get_user_level(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][Level]
}

public 
_crxranks_get_user_next_rank(iPluginiParams)
{
    
set_string(2g_ePlayerData[get_param(1)][NextRank], get_param(3))
}

public 
_crxranks_get_user_next_xp(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][NextXP]
}

public 
_crxranks_get_user_rank(iPluginiParams)
{
    
set_string(2g_ePlayerData[get_param(1)][Rank], get_param(3))
}

public 
_crxranks_get_user_xp(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][XP]
}

public 
_crxranks_get_vault_name(iPluginiParams)
{
    
set_string(1g_eSettings[VAULT_NAME], get_param(2))
}

public 
_crxranks_get_vip_flags(iPluginiParams)
{
    
set_string(1g_eSettings[VIP_FLAGS], get_param(2))
    return 
g_eSettings[VIP_FLAGS_BIT]
}

public 
_crxranks_get_xp_for_level(iPluginiParams)
{
    static 
iLevel
    iLevel 
get_param(1)

    if(
iLevel || iLevel g_iMaxLevels)
    {
        return -
1
    
}

    return 
ArrayGetCell(g_aLevelsiLevel)
}

public 
_crxranks_get_xp_reward(iPluginiParams)
{
    static 
szReward[CRXRANKS_MAX_XP_REWARD_LENGTH]
    
get_string(2szRewardcharsmax(szReward))
    return 
get_xp_reward(get_param(1), szReward)
}

public 
_crxranks_give_user_xp(iPluginiParams)
{
    static 
szReward[CRXRANKS_MAX_XP_REWARD_LENGTH], iRewardid

    szReward
[0] = EOS
    id 
get_param(1)
    
get_string(3szRewardcharsmax(szReward))

    if(
szReward[0])
    {
        
iReward get_xp_reward(idszReward)

        if(
iReward)
        {
            
give_user_xp(idiRewardCRXRanks_XPSources:get_param(3))
        }

        return 
iReward
    
}

    
iReward get_param(2)
    
give_user_xp(idiRewardCRXRanks_XPSources:get_param(3))
    return 
iReward
}

public 
bool:_crxranks_is_hi_using_dhud(iPluginiParams)
{
    return 
g_eSettings[HUDINFO_USE_DHUD]
}

public 
bool:_crxranks_is_hud_enabled(iPluginiParams)
{
    return 
g_eSettings[HUDINFO_ENABLED]
}

public 
bool:_crxranks_is_sfdn_enabled(iPluginiParams)
{
    return 
g_eSettings[LEVELDN_SCREEN_FADE_ENABLED]
}

public 
bool:_crxranks_is_sfup_enabled(iPluginiParams)
{
    return 
g_eSettings[LEVELUP_SCREEN_FADE_ENABLED]
}

public 
bool:_crxranks_is_user_on_final(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][IsOnFinalLevel]
}

public 
bool:_crxranks_is_user_vip(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][IsVIP]
}

public 
bool:_crxranks_is_using_mysql(iPluginiParams)
{
    return 
g_eSettings[USE_MYSQL]
}

public 
bool:_crxranks_is_xpn_enabled(iPluginiParams)
{
    return 
g_eSettings[XP_NOTIFIER_ENABLED]
}

public 
bool:_crxranks_set_user_xp(iPluginiParams)
{
    static 
idiReturnCRXRanks_XPSources:iSource
    id 
get_param(1)
    
iSource CRXRanks_XPSources:get_param(3)
    
g_ePlayerData[id][XP] = clamp(get_param(2), 0)

    
check_level(idtrue)
    
ExecuteForward(g_fwdUserXPUpdatediReturnidg_ePlayerData[id][XP], iSource)
}

public 
bool:_crxranks_using_comb_events(iPluginiParams)
{
    return 
g_eSettings[USE_COMBINED_EVENTS]
}

public 
bool:_crxranks_is_xpn_using_dhud(iPluginiParams)
{
    return 
g_eSettings[XP_NOTIFIER_USE_DHUD]

@Supergirl - I'm not very sure how exactly that's going to work. Pretty sure a huge portion of the code needs to be completely changed in order to implement such a thing so I don't think it's a good idea from coding perspective.
__________________
OciXCrom is offline
Send a message via Skype™ to OciXCrom
LithuanianJack
Senior Member
Join Date: Nov 2013
Location: Vilnius, Lithuania
Old 02-10-2019 , 12:08   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #193

Quote:
Originally Posted by OciXCrom View Post
@LithuanianJack - try this. I used the SQL_QuoteString function in all places where the player name is used, as well as the rank and next rank fields since they can contain problematic symbols as well.

PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <nvault>
#include <sqlx>

// Comment or remove this line in order to run the plugin on a mod different than Counter-Strike.
#define USE_CSTRIKE

#if defined USE_CSTRIKE
    #include <cromchat>
    #include <csx>
#else
new CC_PREFIX[64]
#endif

#if AMXX_VERSION_NUM < 183
    #include <dhudmessage>
#endif

#include <crxranks_const>

#if !defined client_disconnected
    #define client_disconnected client_disconnect
#endif

#if !defined replace_string
    #define replace_string replace_all
#endif

new const PLUGIN_VERSION[] = "3.1a"
const Float:DELAY_ON_CONNECT 5.0
const Float:HUD_REFRESH_FREQ 1.0
const Float:DELAY_ON_CHANGE 0.1
const MAX_SQL_LENGTH 512
const MAX_QUERY_LENGTH 256
const MAX_SOUND_LENGTH 128
const MAX_SQL_PLAYER_LENGTH 64
const MAX_SQL_RANK_LENGTH CRXRANKS_MAX_RANK_LENGTH 2
const TASK_HUD 304500

#if !defined MAX_NAME_LENGTH
const MAX_NAME_LENGTH 32
#endif

new const ARG_CURRENT_XP[]          = "$current_xp$"
new const ARG_NEXT_XP[]             = "$next_xp$"
new const ARG_XP_NEEDED[]           = "$xp_needed$"
new const ARG_LEVEL[]               = "$level$"
new const ARG_NEXT_LEVEL[]          = "$next_level$"
new const ARG_RANK[]                = "$rank$"
new const ARG_NEXT_RANK[]           = "$next_rank$"
new const ARG_MAX_LEVELS[]          = "$max_levels$"
new const ARG_LINE_BREAK[]          = "$br$"
new const ARG_NAME[]                = "$name$"

new const XPREWARD_KILL[]           = "kill"
new const XPREWARD_HEADSHOT[]       = "headshot"
new const XPREWARD_TEAMKILL[]       = "teamkill"
new const XPREWARD_SUICIDE[]        = "suicide"

#if defined USE_CSTRIKE
new const XPREWARD_BOMB_PLANTED[]   = "bomb_planted"
new const XPREWARD_BOMB_DEFUSED[]   = "bomb_defused"
new const XPREWARD_BOMB_EXPLODED[]  = "bomb_exploded"
#endif

#define clr(%1) %1 == -1 ? random(256) : %1

#define HUDINFO_PARAMS clr(g_eSettings[HUDINFO_COLOR][0]), clr(g_eSettings[HUDINFO_COLOR][1]), clr(g_eSettings[HUDINFO_COLOR][2]),\
g_eSettings[HUDINFO_POSITION][0], g_eSettings[HUDINFO_POSITION][1], 00.11.00.10.1

#define XP_NOTIFIER_PARAMS_GET clr(g_eSettings[XP_NOTIFIER_COLOR_GET][0]), clr(g_eSettings[XP_NOTIFIER_COLOR_GET][1]), clr(g_eSettings[XP_NOTIFIER_COLOR_GET][2]),\
g_eSettings[XP_NOTIFIER_POSITION][0], g_eSettings[XP_NOTIFIER_POSITION][1], .holdtime g_eSettings[XP_NOTIFIER_DURATION]

#define XP_NOTIFIER_PARAMS_LOSE clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][0]), clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][1]), clr(g_eSettings[XP_NOTIFIER_COLOR_LOSE][2]),\
g_eSettings[XP_NOTIFIER_POSITION][0], g_eSettings[XP_NOTIFIER_POSITION][1], .holdtime g_eSettings[XP_NOTIFIER_DURATION]

enum _:SaveLoad
{
    
SL_SAVE_DATA,
    
SL_LOAD_DATA
}

enum _:Objects
{
    
OBJ_HUDINFO,
    
OBJ_XP_NOTIFIER
}

enum _:SaveTypes
{
    
SAVE_NICKNAME,
    
SAVE_IP,
    
SAVE_STEAMID
}

enum _:SaveMethods
{
    
SAVE_NVAULT,
    
SAVE_MYSQL
}

enum _:Sections
{
    
SECTION_NONE,
    
SECTION_SETTINGS,
    
SECTION_RANKS,
    
SECTION_XP_REWARDS
}

enum _:PlayerData
{
    
XP,
    
Level,
    
NextXP,
    
Rank[CRXRANKS_MAX_RANK_LENGTH],
    
NextRank[CRXRANKS_MAX_RANK_LENGTH],
    
HUDInfo[CRXRANKS_MAX_HUDINFO_LENGTH],
    
bool:IsOnFinalLevel,
    
bool:IsVIP,
    
bool:IsBot
}

enum _:Settings
{
    
SAVE_TYPE,
    
bool:USE_MYSQL,
    
SQL_HOST[MAX_NAME_LENGTH],
    
SQL_USER[MAX_NAME_LENGTH],
    
SQL_PASSWORD[MAX_NAME_LENGTH],
    
SQL_DATABASE[MAX_NAME_LENGTH],
    
SQL_TABLE[MAX_NAME_LENGTH],
    
LEVELUP_MESSAGE_TYPE,
    
LEVELUP_SOUND[MAX_SOUND_LENGTH],
    
bool:LEVELUP_SCREEN_FADE_ENABLED,
    
LEVELUP_SCREEN_FADE_COLOR[4],
    
LEVELDN_SOUND[MAX_SOUND_LENGTH],
    
bool:LEVELDN_SCREEN_FADE_ENABLED,
    
LEVELDN_SCREEN_FADE_COLOR[4],
    
FINAL_LEVEL_FLAGS[32],
    
FINAL_LEVEL_FLAGS_BIT,
    
VIP_FLAGS[32],
    
VIP_FLAGS_BIT,
    
VAULT_NAME[32],
    
TEAM_LOCK,
    
MINIMUM_PLAYERS,
    
bool:IGNORE_BOTS,
    
bool:USE_COMBINED_EVENTS,
    
bool:NOTIFY_ON_KILL,
    
bool:HUDINFO_ENABLED,
    
bool:HUDINFO_ALIVE_ONLY,
    
bool:HUDINFO_TEAM_LOCK,
    
bool:HUDINFO_OTHER_PLAYERS,
    
HUDINFO_COLOR[3],
    
Float:HUDINFO_POSITION[2],
    
bool:HUDINFO_USE_DHUD,
    
HUDINFO_FORMAT[CRXRANKS_MAX_HUDINFO_LENGTH],
    
HUDINFO_FORMAT_FINAL[CRXRANKS_MAX_HUDINFO_LENGTH],
    
HUDINFO_INVALID_TEXT[32],
    
bool:XP_NOTIFIER_ENABLED,
    
XP_NOTIFIER_COLOR_GET[3],
    
XP_NOTIFIER_COLOR_LOSE[3],
    
Float:XP_NOTIFIER_POSITION[2],
    
Float:XP_NOTIFIER_DURATION,
    
bool:XP_NOTIFIER_USE_DHUD
}

new 
g_eSettings[Settings]
new 
g_ePlayerData[33][PlayerData]
new 
g_szMaxLevels[CRXRANKS_MAX_XP_LENGTH]
new 
g_szSqlError[MAX_SQL_LENGTH]
new 
Handle:g_iSqlTuple
new Array:g_aLevels
new Array:g_aRankNames
new Trie:g_tSettings
new Trie:g_tXPRewards
new Trie:g_tXPRewardsVIP

new g_iVault
new g_iMaxLevels
new g_iFlagZ
new g_iScreenFade
new g_iObject[2]

new 
g_fwdUserLevelUpdated
new g_fwdUserReceiveXP
new g_fwdUserXPUpdated

public plugin_init()
{
    
register_plugin("OciXCrom's Rank System"PLUGIN_VERSION"OciXCrom")
    
register_cvar("CRXRankSystem"PLUGIN_VERSIONFCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)

    
#if defined USE_CSTRIKE
    
register_dictionary("RankSystem.txt")
    
#else
    
register_dictionary("RankSystemNoColors.txt")
    
#endif

    
register_event("DeathMsg""OnPlayerKilled""a")

    
register_clcmd("say /xplist",            "Cmd_XPList",      ADMIN_BAN)
    
register_clcmd("say_team /xplist",       "Cmd_XPList",      ADMIN_BAN)
    
register_concmd("crxranks_give_xp",      "Cmd_GiveXP",      ADMIN_RCON"<nick|#userid> <amount>")
    
register_concmd("crxranks_reset_xp",     "Cmd_ResetXP",     ADMIN_RCON"<nick|#userid>")
    
register_srvcmd("crxranks_update_mysql""Cmd_UpdateMySQL")

    if(
g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] || g_eSettings[LEVELDN_SCREEN_FADE_ENABLED])
    {
        
g_iScreenFade get_user_msgid("ScreenFade")
    }

    
g_fwdUserLevelUpdated CreateMultiForward("crxranks_user_level_updated"ET_IGNOREFP_CELLFP_CELLFP_CELL)
    
g_fwdUserReceiveXP    CreateMultiForward("crxranks_user_receive_xp",    ET_STOP,   FP_CELLFP_CELLFP_CELL)
    
g_fwdUserXPUpdated    CreateMultiForward("crxranks_user_xp_updated",    ET_IGNOREFP_CELLFP_CELLFP_CELL)

    if(
g_eSettings[USE_MYSQL])
    {
        
g_iSqlTuple SQL_MakeDbTuple(g_eSettings[SQL_HOST], g_eSettings[SQL_USER], g_eSettings[SQL_PASSWORD], g_eSettings[SQL_DATABASE])

        new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

        if(
iSqlConnection == Empty_Handle)
        {
            
log_amx(g_szSqlError)
            
switch_to_nvault()
            goto @
AFTER_MYSQL
        
}

        new 
Handle:iQueries SQL_PrepareQuery(iSqlConnection,\
        
"CREATE TABLE IF NOT EXISTS `%s` (`Player` VARCHAR(%i) NOT NULL, `XP` INT(%i) NOT NULL, `Level` INT(%i) NOT NULL,\
        `Next XP` INT(%i) NOT NULL, `Rank` VARCHAR(%i) NOT NULL, `Next Rank` VARCHAR(%i) NOT NULL, PRIMARY KEY(Player));"
,\
        
g_eSettings[SQL_TABLE], MAX_SQL_PLAYER_LENGTHCRXRANKS_MAX_XP_LENGTHCRXRANKS_MAX_XP_LENGTHCRXRANKS_MAX_XP_LENGTH,\
        
MAX_SQL_RANK_LENGTHMAX_SQL_RANK_LENGTH)

        if(!
SQL_Execute(iQueries))
        {
            
SQL_QueryError(iQueriesg_szSqlErrorcharsmax(g_szSqlError))
            
log_amx(g_szSqlError)
            
switch_to_nvault()
            goto @
AFTER_MYSQL
        
}

        
SQL_FreeHandle(iQueries)
        
SQL_FreeHandle(iSqlConnection)
    }

    @
AFTER_MYSQL:

    if(!
g_eSettings[USE_MYSQL])
    {
        
g_iVault nvault_open(g_eSettings[VAULT_NAME])
    }
}

public 
plugin_precache()
{
    
g_aLevels ArrayCreate(16)
    
ArrayPushCell(g_aLevels0)

    
g_aRankNames ArrayCreate(32)
    
ArrayPushString(g_aRankNames"")

    
g_tSettings TrieCreate()
    
g_tXPRewards TrieCreate()
    
g_tXPRewardsVIP TrieCreate()

    
ReadFile()
}

public 
plugin_end()
{
    
ArrayDestroy(g_aLevels)
    
ArrayDestroy(g_aRankNames)
    
TrieDestroy(g_tSettings)
    
TrieDestroy(g_tXPRewards)
    
TrieDestroy(g_tXPRewardsVIP)
    
DestroyForward(g_fwdUserLevelUpdated)

    if(!
g_eSettings[USE_MYSQL])
    {
        
nvault_close(g_iVault)
    }
}

ReadFile()
{
    new 
szFilename[256]
    
get_configsdir(szFilenamecharsmax(szFilename))
    
add(szFilenamecharsmax(szFilename), "/RankSystem.ini")

    new 
iFilePointer fopen(szFilename"rt")

    if(
iFilePointer)
    {
        new 
szData[CRXRANKS_MAX_HUDINFO_LENGTH MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], szMap[MAX_NAME_LENGTH], szKey[MAX_NAME_LENGTH]
        new 
szTemp[4][5], bool:bRead trueiiSizeiSection SECTION_NONE
        get_mapname
(szMapcharsmax(szMap))

        while(!
feof(iFilePointer))
        {
            
fgets(iFilePointerszDatacharsmax(szData))
            
trim(szData)

            switch(
szData[0])
            {
                case 
EOS'#'';': continue
                case 
'-':
                {
                    
iSize strlen(szData)

                    if(
szData[iSize 1] == '-')
                    {
                        
szData[0] = ' '
                        
szData[iSize 1] = ' '
                        
trim(szData)

                        if(
contain(szData"*") != -1)
                        {
                            
strtok(szDataszKeycharsmax(szKey), szValuecharsmax(szValue), '*')
                            
copy(szValuestrlen(szKey), szMap)
                            
bRead equal(szValueszKey) ? true false
                        
}
                        else
                        {
                            static const 
szAll[] = "#all"
                            
bRead equal(szDataszAll) || equali(szDataszMap)
                        }
                    }
                    else continue
                }
                case 
'[':
                {
                    
iSize strlen(szData)

                    if(
szData[iSize 1] == ']')
                    {
                        switch(
szData[1])
                        {
                            case 
'S''s'iSection SECTION_SETTINGS
                            
case 'R''r'iSection SECTION_RANKS
                            
case 'X''x'iSection SECTION_XP_REWARDS
                            
default: iSection SECTION_NONE
                        
}
                    }
                    else continue
                }
                default:
                {
                    if(!
bRead || iSection == SECTION_NONE)
                    {
                        continue
                    }

                    
strtok(szDataszKeycharsmax(szKey), szValuecharsmax(szValue), '=')
                    
trim(szKey); trim(szValue)

                    if(!
szValue[0])
                    {
                        continue
                    }

                    switch(
iSection)
                    {
                        case 
SECTION_SETTINGS:
                        {
                            
TrieSetString(g_tSettingsszKeyszValue)

                            if(
equal(szKey"CHAT_PREFIX"))
                            {
                                
#if defined USE_CSTRIKE
                                
CC_SetPrefix(szValue)
                                
#else
                                
copy(CC_PREFIXcharsmax(CC_PREFIX), szValue)
                                
#endif
                            
}
                            else if(
equal(szKey"SAVE_TYPE"))
                            {
                                
g_eSettings[SAVE_TYPE] = clamp(str_to_num(szValue), SAVE_NICKNAMESAVE_STEAMID)
                            }
                            else if(
equal(szKey"USE_MYSQL"))
                            {
                                
g_eSettings[USE_MYSQL] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"SQL_HOST"))
                            {
                                
copy(g_eSettings[SQL_HOST], charsmax(g_eSettings[SQL_HOST]), szValue)
                            }
                            else if(
equal(szKey"SQL_USER"))
                            {
                                
copy(g_eSettings[SQL_USER], charsmax(g_eSettings[SQL_USER]), szValue)
                            }
                            else if(
equal(szKey"SQL_PASSWORD"))
                            {
                                
copy(g_eSettings[SQL_PASSWORD], charsmax(g_eSettings[SQL_PASSWORD]), szValue)
                            }
                            else if(
equal(szKey"SQL_DATABASE"))
                            {
                                
copy(g_eSettings[SQL_DATABASE], charsmax(g_eSettings[SQL_DATABASE]), szValue)
                            }
                            else if(
equal(szKey"SQL_TABLE"))
                            {
                                
copy(g_eSettings[SQL_TABLE], charsmax(g_eSettings[SQL_TABLE]), szValue)
                            }
                            else if(
equal(szKey"XP_COMMANDS"))
                            {
                                while(
szValue[0] != && strtok(szValueszKeycharsmax(szKey), szValuecharsmax(szValue), ','))
                                {
                                    
trim(szKey); trim(szValue)
                                    
register_clcmd(szKey"Cmd_XP")
                                }
                            }
                            else if(
equal(szKey"LEVELUP_MESSAGE_TYPE"))
                            {
                                
g_eSettings[LEVELUP_MESSAGE_TYPE] = clamp(str_to_num(szValue), 02)
                            }
                            else if(
equal(szKey"LEVELUP_SOUND"))
                            {
                                
copy(g_eSettings[LEVELUP_SOUND], charsmax(g_eSettings[LEVELUP_SOUND]), szValue)

                                if(
szValue[0])
                                {
                                    
precache_sound(szValue)
                                }
                            }
                            else if(
equal(szKey"LEVELUP_SCREEN_FADE_ENABLED"))
                            {
                                
g_eSettings[LEVELUP_SCREEN_FADE_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"LEVELUP_SCREEN_FADE_COLOR"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]), szTemp[3], charsmax(szTemp[]))

                                for(
04i++)
                                {
                                    
g_eSettings[LEVELUP_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"LEVELDN_SOUND"))
                            {
                                
copy(g_eSettings[LEVELDN_SOUND], charsmax(g_eSettings[LEVELDN_SOUND]), szValue)

                                if(
szValue[0])
                                {
                                    
precache_sound(szValue)
                                }
                            }
                            else if(
equal(szKey"LEVELDN_SCREEN_FADE_ENABLED"))
                            {
                                
g_eSettings[LEVELDN_SCREEN_FADE_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"LEVELDN_SCREEN_FADE_COLOR"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]), szTemp[3], charsmax(szTemp[]))

                                for(
04i++)
                                {
                                    
g_eSettings[LEVELDN_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"FINAL_LEVEL_FLAGS"))
                            {
                                
copy(g_eSettings[FINAL_LEVEL_FLAGS], charsmax(g_eSettings[FINAL_LEVEL_FLAGS]), szValue)
                                
g_eSettings[FINAL_LEVEL_FLAGS_BIT] = read_flags(szValue)
                                
g_iFlagZ read_flags("z")
                            }
                            else if(
equal(szKey"VIP_FLAGS"))
                            {
                                
copy(g_eSettings[VIP_FLAGS], charsmax(g_eSettings[VIP_FLAGS]), szValue)
                                
g_eSettings[VIP_FLAGS_BIT] = read_flags(szValue)
                            }
                            else if(
equal(szKey"VAULT_NAME"))
                            {
                                
copy(g_eSettings[VAULT_NAME], charsmax(g_eSettings[VAULT_NAME]), szValue)
                            }
                            else if(
equal(szKey"TEAM_LOCK"))
                            {
                                
g_eSettings[TEAM_LOCK] = str_to_num(szValue)
                            }
                            else if(
equal(szKey"MINIMUM_PLAYERS"))
                            {
                                
g_eSettings[MINIMUM_PLAYERS] = clamp(str_to_num(szValue), 032)
                            }
                            else if(
equal(szKey"IGNORE_BOTS"))
                            {
                                
g_eSettings[IGNORE_BOTS] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"USE_COMBINED_EVENTS"))
                            {
                                
g_eSettings[USE_COMBINED_EVENTS] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"NOTIFY_ON_KILL"))
                            {
                                
g_eSettings[NOTIFY_ON_KILL] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_ENABLED"))
                            {
                                
g_eSettings[HUDINFO_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_ALIVE_ONLY"))
                            {
                                
g_eSettings[HUDINFO_ALIVE_ONLY] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_TEAM_LOCK"))
                            {
                                
g_eSettings[HUDINFO_TEAM_LOCK] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_OTHER_PLAYERS"))
                            {
                                
g_eSettings[HUDINFO_OTHER_PLAYERS] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"HUDINFO_COLOR"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

                                for(
03i++)
                                {
                                    
g_eSettings[HUDINFO_COLOR][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"HUDINFO_POSITION"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

                                for(
02i++)
                                {
                                    
g_eSettings[HUDINFO_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.01.0)
                                }
                            }
                            else if(
equal(szKey"HUDINFO_USE_DHUD"))
                            {
                                
g_eSettings[HUDINFO_USE_DHUD] = _:clamp(str_to_num(szValue), falsetrue)

                                if(!
g_eSettings[HUDINFO_USE_DHUD])
                                {
                                    
g_iObject[OBJ_HUDINFO] = CreateHudSyncObj()
                                }
                            }
                            else if(
equal(szKey"HUDINFO_FORMAT"))
                            {
                                
copy(g_eSettings[HUDINFO_FORMAT], charsmax(g_eSettings[HUDINFO_FORMAT]), szValue)
                            }
                            else if(
equal(szKey"HUDINFO_FORMAT_FINAL"))
                            {
                                
copy(g_eSettings[HUDINFO_FORMAT_FINAL], charsmax(g_eSettings[HUDINFO_FORMAT_FINAL]), szValue)
                            }
                            else if(
equal(szKey"HUDINFO_INVALID_TEXT"))
                            {
                                
copy(g_eSettings[HUDINFO_INVALID_TEXT], charsmax(g_eSettings[HUDINFO_INVALID_TEXT]), szValue)
                            }
                            else if(
equal(szKey"XP_NOTIFIER_ENABLED"))
                            {
                                
g_eSettings[XP_NOTIFIER_ENABLED] = _:clamp(str_to_num(szValue), falsetrue)
                            }
                            else if(
equal(szKey"XP_NOTIFIER_COLOR_GET"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

                                for(
03i++)
                                {
                                    
g_eSettings[XP_NOTIFIER_COLOR_GET][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"XP_NOTIFIER_COLOR_LOSE"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

                                for(
03i++)
                                {
                                    
g_eSettings[XP_NOTIFIER_COLOR_LOSE][i] = clamp(str_to_num(szTemp[i]), -1255)
                                }
                            }
                            else if(
equal(szKey"XP_NOTIFIER_POSITION"))
                            {
                                
parse(szValueszTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

                                for(
02i++)
                                {
                                    
g_eSettings[XP_NOTIFIER_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.01.0)
                                }
                            }
                            else if(
equal(szKey"XP_NOTIFIER_DURATION"))
                            {
                                
g_eSettings[XP_NOTIFIER_DURATION] = _:floatclamp(str_to_float(szValue), 0.0float(cellmax))
                            }
                            else if(
equal(szKey"XP_NOTIFIER_USE_DHUD"))
                            {
                                
g_eSettings[XP_NOTIFIER_USE_DHUD] = _:clamp(str_to_num(szValue), falsetrue)

                                if(!
g_eSettings[XP_NOTIFIER_USE_DHUD])
                                {
                                    
g_iObject[OBJ_XP_NOTIFIER] = CreateHudSyncObj()
                                }
                            }
                        }
                        case 
SECTION_RANKS:
                        {
                            
ArrayPushCell(g_aLevelsclamp(str_to_num(szValue), 0))
                            
ArrayPushString(g_aRankNamesszKey)
                            
g_iMaxLevels++
                        }
                        case 
SECTION_XP_REWARDS:
                        {
                            static 
szReward[2][16]
                            
szReward[1][0] = EOS

                            parse
(szValueszReward[0], charsmax(szReward[]), szReward[1], charsmax(szReward[]))
                            
TrieSetCell(g_tXPRewardsszKeystr_to_num(szReward[0]))

                            if(
szReward[1][0])
                            {
                                
TrieSetCell(g_tXPRewardsVIPszKeystr_to_num(szReward[1]))
                            }
                        }
                    }
                }
            }
        }

        
num_to_str(g_iMaxLevelsg_szMaxLevelscharsmax(g_szMaxLevels))
        
fclose(iFilePointer)
    }
}

public 
client_connect(id)
{
    
reset_player_stats(id)

    new 
szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH]
    
get_user_saveinfo(idszInfocharsmax(szInfo))
    
save_or_load(idszInfoSL_LOAD_DATA)

    
g_ePlayerData[id][IsBot] = is_user_bot(id) != 0
    set_task
(DELAY_ON_CONNECT"update_vip_status"id)

    if(
g_eSettings[HUDINFO_ENABLED])
    {
        
set_task(HUD_REFRESH_FREQ"DisplayHUD"id TASK_HUD, .flags "b")
    }
}

public 
client_disconnected(id)
{
    new 
szInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH]
    
get_user_saveinfo(idszInfocharsmax(szInfo))
    
save_or_load(idszInfoSL_SAVE_DATA)
    
remove_task(id TASK_HUD)
}

public 
client_infochanged(id)
{
    if(!
is_user_connected(id))
    {
        return
    }

    static const 
szKey[] = "name"
    
static szNewName[MAX_NAME_LENGTH], szOldName[MAX_NAME_LENGTH]
    
get_user_info(idszKeyszNewNamecharsmax(szNewName))
    
get_user_name(idszOldNamecharsmax(szOldName))

    if(!
equal(szNewNameszOldName))
    {
        if(
g_eSettings[SAVE_TYPE] == SAVE_NICKNAME)
        {
            
save_or_load(idszOldNameSL_SAVE_DATA)

            if(
g_eSettings[USE_MYSQL])
            {
                
reset_player_stats(id)
                
set_task(DELAY_ON_CHANGE"load_after_change"id)
            }
            else
            {
                
save_or_load(idszNewNameSL_LOAD_DATA)
                
update_hudinfo(id)
            }
        }

        
set_task(DELAY_ON_CHANGE"update_vip_status"id)
    }
}

public 
load_after_change(id)
{
    static 
szName[MAX_NAME_LENGTH]
    
get_user_name(idszNamecharsmax(szName))
    
save_or_load(idszNameSL_LOAD_DATA)
    
update_hudinfo(id)
}

public 
DisplayHUD(id)
{
    
id -= TASK_HUD

    
static iTarget
    iTarget 
id

    
if(!is_user_alive(id))
    {
        if(
g_eSettings[HUDINFO_ALIVE_ONLY])
        {
            return
        }

        if(
g_eSettings[HUDINFO_OTHER_PLAYERS])
        {
            
iTarget pev(idpev_iuser2)
        }
    }

    if(!
iTarget)
    {
        return
    }

    if(
g_eSettings[TEAM_LOCK] && g_eSettings[HUDINFO_TEAM_LOCK] && get_user_team(iTarget) != g_eSettings[TEAM_LOCK])
    {
        return
    }

    if(
g_eSettings[HUDINFO_USE_DHUD])
    {
        
set_dhudmessage(HUDINFO_PARAMS)
        
show_dhudmessage(idg_ePlayerData[iTarget][HUDInfo])
    }
    else
    {
        
set_hudmessage(HUDINFO_PARAMS)
        
ShowSyncHudMsg(idg_iObject[OBJ_HUDINFO], g_ePlayerData[iTarget][HUDInfo])
    }
}

#if defined USE_CSTRIKE
public bomb_planted(id)
{
    
give_user_xp(idget_xp_reward(idXPREWARD_BOMB_PLANTED), CRXRANKS_XPS_REWARD)
}

public 
bomb_defused(id)
{
    
give_user_xp(idget_xp_reward(idXPREWARD_BOMB_DEFUSED), CRXRANKS_XPS_REWARD)
}

public 
bomb_explode(id)
{
    
give_user_xp(idget_xp_reward(idXPREWARD_BOMB_EXPLODED), CRXRANKS_XPS_REWARD)
}
#endif

public Cmd_XP(id)
{
    if(
g_ePlayerData[id][Level] == g_iMaxLevels)
    {
        
send_chat_message(idfalse"%L"id"CRXRANKS_RANKINFO_FINAL"g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
    }
    else
    {
        
send_chat_message(idfalse"%L"id"CRXRANKS_RANKINFO_NORMAL"g_ePlayerData[id][XP], g_ePlayerData[id][NextXP],\
        
g_ePlayerData[id][Level], g_ePlayerData[id][Rank], g_ePlayerData[id][NextRank])
    }

    return 
PLUGIN_HANDLED
}

public 
Cmd_XPList(idiLeveliCid)
{
    if(!
cmd_access(idiLeveliCid1))
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szTitle[128]
    
formatex(szTitlecharsmax(szTitle), "%L"id"CRXRANKS_MENU_TITLE")

    new 
iPlayers[32], iPnumiMenu menu_create(szTitle"XPList_Handler")
    
get_players(iPlayersiPnum); SortCustom1D(iPlayersiPnum"sort_players_by_xp")

    for(new 
szItem[128], szName[32], iPlayeriiPnumi++)
    {
        
iPlayer iPlayers[i]
        
get_user_name(iPlayerszNamecharsmax(szName))
        
formatex(szItemcharsmax(szItem), "%L"id"CRXRANKS_ITEM_FORMAT"g_ePlayerData[iPlayer][XP], szNameg_ePlayerData[iPlayer][Level], g_ePlayerData[iPlayer][Rank])
        
menu_additem(iMenuszItem)
    }

    
menu_display(idiMenu)
    return 
PLUGIN_HANDLED
}

public 
XPList_Handler(idiMenuiItem)
{
    
menu_destroy(iMenu)
    return 
PLUGIN_HANDLED
}

public 
Cmd_GiveXP(idiLeveliCid)
{
    if(!
cmd_access(idiLeveliCid3))
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szPlayer[MAX_NAME_LENGTH]
    
read_argv(1szPlayercharsmax(szPlayer))

    new 
iPlayer cmd_target(idszPlayer0)

    if(!
iPlayer)
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szName[2][MAX_NAME_LENGTH], szAmount[CRXRANKS_MAX_XP_LENGTH]
    
read_argv(2szAmountcharsmax(szAmount))
    
get_user_name(idszName[0], charsmax(szName[]))
    
get_user_name(iPlayerszName[1], charsmax(szName[]))

    new 
szKey[32], iXP str_to_num(szAmount)
    
give_user_xp(iPlayeriXPCRXRANKS_XPS_ADMIN)

    if(
iXP >= 0)
    {
        
copy(szKeycharsmax(szKey), "CRXRANKS_GIVE_XP")
    }
    else
    {
        
copy(szKeycharsmax(szKey), "CRXRANKS_TAKE_XP")
        
iXP *= -1
    
}

    
send_chat_message(0true"%L"idszKeyszName[0], iXPszName[1])
    return 
PLUGIN_HANDLED
}

public 
Cmd_ResetXP(idiLeveliCid)
{
    if(!
cmd_access(idiLeveliCid2))
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szPlayer[MAX_NAME_LENGTH]
    
read_argv(1szPlayercharsmax(szPlayer))

    new 
iPlayer cmd_target(idszPlayerCMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF)

    if(!
iPlayer)
    {
        return 
PLUGIN_HANDLED
    
}

    new 
szName[2][MAX_NAME_LENGTH]
    
get_user_name(idszName[0], charsmax(szName[]))
    
get_user_name(iPlayerszName[1], charsmax(szName[]))

    
g_ePlayerData[iPlayer][XP] = 0
    check_level
(iPlayertrue)
    
send_chat_message(0true"%L"id"CRXRANKS_RESET_XP"szName[0], szName[1])

    return 
PLUGIN_HANDLED
}

// This command is here because the update from v3.0 to v3.1 changed the way data is stored in MySQL.
// Because of that, a new table is required and this command is here to transfer the data from the old one.
// The command will be removed in future versions, so I decided not to translate the strings used in it.
public Cmd_UpdateMySQL()
{
    static 
bUsed

    
if(bUsed)
    {
        
server_print("The MySQL table has already been updated to version v3.1. There's no point in doing this again.")
        return 
PLUGIN_HANDLED
    
}

    if(!
g_eSettings[USE_MYSQL])
    {
        
server_print("The plugin isn't using MySQL at the moment. Please enable the feature before using this command.")
        return 
PLUGIN_HANDLED
    
}

    new 
szTable[MAX_NAME_LENGTH]
    
read_argv(1szTablecharsmax(szTable))

    if(!
szTable[0])
    {
        
server_print("Plese provide the name of the previous table in order to transfer data to the current one.")
        return 
PLUGIN_HANDLED
    
}

    new 
szQuery[MAX_NAME_LENGTH 2]
    
formatex(szQuerycharsmax(szQuery), "SELECT * FROM `%s`;"szTable)
    
SQL_ThreadQuery(g_iSqlTuple"QueryUpdateMySQL"szQuery)

    
bUsed true
    
return PLUGIN_HANDLED
}

public 
QueryUpdateMySQL(iFailStateHandle:iQueryszError[], iErrorCode)
{
    if(
iFailState == TQUERY_CONNECT_FAILED || iFailState == TQUERY_QUERY_FAILED)
    {
        
server_print(szError)
        return
    }

    new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

    if(
iSqlConnection == Empty_Handle)
    {
        
server_print(g_szSqlError)
        return
    }

    new 
Handle:iQuery2szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szInfo[MAX_SQL_PLAYER_LENGTH], iCounteriPlayeriXP
    
new szColumnPlayer SQL_FieldNameToNum(iQuery"User")
    new 
szColumnXP SQL_FieldNameToNum(iQuery"XP")

    while(
SQL_MoreResults(iQuery))
    {
        
SQL_ReadResult(iQueryszColumnPlayerszInfocharsmax(szInfo))
        
SQL_QuoteString(iSqlConnectionszPlayercharsmax(szPlayer), szInfo)
        
iQuery2 SQL_PrepareQuery(iSqlConnection"SELECT * FROM %s WHERE Player = '%s';"g_eSettings[SQL_TABLE], szPlayer)

        if(!
SQL_Execute(iQuery2))
        {
            
SQL_QueryError(iQuery2g_szSqlErrorcharsmax(g_szSqlError))
            
server_print(g_szSqlError)
            return
        }

        
iXP SQL_ReadResult(iQueryszColumnXP)

        if(
SQL_NumResults(iQuery2) > 0)
        {
            
formatex(szQuerycharsmax(szQuery), "UPDATE `%s` SET `XP`='%i' WHERE `Player`='%s';"g_eSettings[SQL_TABLE], iXPszPlayer)
        }
        else
        {
            
formatex(szQuerycharsmax(szQuery), "INSERT INTO %s (`Player`,`XP`,`Level`,`Next XP`,`Rank`,`Next Rank`) VALUES ('%s','%i','1','0','n/a','n/a');"g_eSettings[SQL_TABLE], szPlayeriXP)
        }

        switch(
g_eSettings[SAVE_TYPE])
        {
            case 
CRXRANKS_ST_NICKNAMEiPlayer find_player("a"szInfo)
            case 
CRXRANKS_ST_STEAMID:  iPlayer find_player("c"szInfo)
            case 
CRXRANKS_ST_IP:       iPlayer find_player("d"szInfo)
        }

        if(
iPlayer)
        {
            
g_ePlayerData[iPlayer][XP] = iXP
            check_level
(iPlayertrue)
        }

        
SQL_ThreadQuery(g_iSqlTuple"QueryHandler"szQuery)
        
SQL_NextRow(iQuery)
        
iCounter++
    }

    
SQL_FreeHandle(iQuery2)
    
SQL_FreeHandle(iSqlConnection)
}

public 
OnPlayerKilled()
{
    new 
iAttacker read_data(1), iVictim read_data(2)

    if(!
is_user_connected(iAttacker) || !is_user_connected(iVictim))
    {
        return
    }

    new 
iRewardiTemp

    
if(iAttacker == iVictim)
    {
        
iTemp get_xp_reward(iAttackerXPREWARD_SUICIDE)
        
iReward += iTemp

        
if(should_skip(iTemp))
        {
            goto @
GIVE_REWARD
        
}
    }
    else if(
get_user_team(iAttacker) == get_user_team(iVictim))
    {
        
iTemp get_xp_reward(iAttackerXPREWARD_TEAMKILL)
        
iReward += iTemp

        
if(should_skip(iTemp))
        {
            goto @
GIVE_REWARD
        
}
    }
    else
    {
        new 
szWeapon[16]
        
read_data(4szWeaponcharsmax(szWeapon))

        
iTemp get_xp_reward(iAttackerszWeapon)
        
iReward += iTemp

        
if(should_skip(iTemp))
        {
            goto @
GIVE_REWARD
        
}

        if(
read_data(3))
        {
            
iTemp get_xp_reward(iAttackerXPREWARD_HEADSHOT)
            
iReward += iTemp

            
if(should_skip(iTemp))
            {
                goto @
GIVE_REWARD
            
}
        }

        
iReward += get_xp_reward(iAttackerXPREWARD_KILL)
    }

    @
GIVE_REWARD:
    new 
iXP give_user_xp(iAttackeriRewardCRXRANKS_XPS_REWARD)

    if(
g_eSettings[NOTIFY_ON_KILL] && iXP != 0)
    {
        if(
iAttacker == iVictim)
        {
            
CC_SendMessage(iAttacker"%L"iAttacker"CRXRANKS_NOTIFY_SUICIDE"abs(iXP))
        }
        else
        {
            new 
szName[MAX_NAME_LENGTH]
            
get_user_name(iVictimszNamecharsmax(szName))
            
CC_SendMessage(iAttacker"%L"iAttackeriXP >= "CRXRANKS_NOTIFY_KILL_GET" "CRXRANKS_NOTIFY_KILL_LOSE"abs(iXP), szName)
        }
    }
}

public 
sort_players_by_xp(id1id2)
{
    if(
g_ePlayerData[id1][XP] > g_ePlayerData[id2][XP])
    {
        return -
1
    
}
    else if(
g_ePlayerData[id1][XP] < g_ePlayerData[id2][XP])
    {
        return 
1
    
}

    return 
0
}

public 
QueryHandler(iFailStateHandle:iQueryszError[], iErrorCode)
{
    switch(
iFailState)
    {
        case 
TQUERY_CONNECT_FAILEDlog_amx("[SQL Error] Connection failed (%i): %s"iErrorCodeszError)
        case 
TQUERY_QUERY_FAILED:   log_amx("[SQL Error] Query failed (%i): %s"iErrorCodeszError)
    }
}

save_or_load(const id, const szInfo[], const iType)
{
    if(!
szInfo[0])
    {
        return
    }

    switch(
iType)
    {
        case 
SL_SAVE_DATA:
        {
            if(
g_eSettings[USE_MYSQL])
            {
                static 
szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szRank[MAX_SQL_RANK_LENGTH], szNextRank[MAX_SQL_RANK_LENGTH]
                new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

                
SQL_QuoteString(iSqlConnectionszPlayercharsmax(szPlayer), szInfo)
                
SQL_QuoteString(iSqlConnectionszRankcharsmax(szRank), g_ePlayerData[id][Rank])
                
SQL_QuoteString(iSqlConnectionszNextRankcharsmax(szNextRank), g_ePlayerData[id][NextRank])

                
formatex(szQuerycharsmax(szQuery), "UPDATE `%s` SET `XP`='%i',`Level`='%i',`Next XP`='%i',`Rank`='%s',`Next Rank`='%s' WHERE `Player`='%s';",\
                
g_eSettings[SQL_TABLE], g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][NextXP], szRankszNextRankszPlayer)
                
SQL_ThreadQuery(g_iSqlTuple"QueryHandler"szQuery)
            }
            else
            {
                static 
szData[CRXRANKS_MAX_XP_LENGTH]
                
num_to_str(g_ePlayerData[id][XP], szDatacharsmax(szData))
                
nvault_set(g_iVaultszInfoszData)
            }
        }
        case 
SL_LOAD_DATA:
        {
            if(
g_eSettings[USE_MYSQL])
            {
                static 
szPlayer[MAX_SQL_PLAYER_LENGTH]
                new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))
                
SQL_QuoteString(iSqlConnectionszPlayercharsmax(szPlayer), szInfo)

                if(
iSqlConnection == Empty_Handle)
                {
                    
log_amx(g_szSqlError)
                    return
                }

                new 
Handle:iQuery SQL_PrepareQuery(iSqlConnection"SELECT * FROM %s WHERE Player = '%s';"g_eSettings[SQL_TABLE], szPlayer)

                if(!
SQL_Execute(iQuery))
                {
                    
SQL_QueryError(iQueryg_szSqlErrorcharsmax(g_szSqlError))
                    
log_amx(g_szSqlError)
                    return
                }

                
prepare_player(idszPlayerSQL_NumResults(iQuery) > false true)
                
SQL_FreeHandle(iQuery)
                
SQL_FreeHandle(iSqlConnection)
            }
            else
            {
                static 
iData
                iData 
nvault_get(g_iVaultszInfo)
                
g_ePlayerData[id][XP] = iData clamp(iData0) : 0
                check_level
(idfalse)
            }
        }
    }
}

prepare_player(id, const szPlayer[], bool:bNewPlayer)
{
    new 
iErrorCodeHandle:iSqlConnection SQL_Connect(g_iSqlTupleiErrorCodeg_szSqlErrorcharsmax(g_szSqlError))

    if(
iSqlConnection == Empty_Handle)
    {
        
log_amx(g_szSqlError)
        return
    }

    static 
szQuery[MAX_QUERY_LENGTH]

    if(
bNewPlayer)
    {
        
formatex(szQuerycharsmax(szQuery), "INSERT INTO %s (`Player`,`XP`,`Level`,`Next XP`,`Rank`,`Next Rank`) VALUES ('%s','0','1','0','n/a','n/a');"g_eSettings[SQL_TABLE], szPlayer)
    }
    else
    {
        
formatex(szQuerycharsmax(szQuery), "SELECT XP FROM %s WHERE Player = '%s';"g_eSettings[SQL_TABLE], szPlayer)
    }

    new 
Handle:iQuery SQL_PrepareQuery(iSqlConnectionszQuery)

    if(!
SQL_Execute(iQuery))
    {
        
SQL_QueryError(iQueryg_szSqlErrorcharsmax(g_szSqlError))
        
log_amx(g_szSqlError)
    }

    if(!
bNewPlayer)
    {
        if(
SQL_NumResults(iQuery) > 0)
        {
            
g_ePlayerData[id][XP] = SQL_ReadResult(iQuery0)
        }
    }

    
check_level(idfalse)

    
SQL_FreeHandle(iQuery)
    
SQL_FreeHandle(iSqlConnection)
}

get_xp_reward(const id, const szKey[])
{
    static 
iReward

    
if(g_ePlayerData[id][IsVIP])
    {
        if(
TrieKeyExists(g_tXPRewardsVIPszKey))
        {
            
TrieGetCell(g_tXPRewardsVIPszKeyiReward)
            return 
iReward
        
}
    }

    if(
TrieKeyExists(g_tXPRewardsszKey))
    {
        
TrieGetCell(g_tXPRewardsszKeyiReward)
        return 
iReward
    
}

    return 
0
}

give_user_xp(const idiXPCRXRanks_XPSources:iSource CRXRANKS_XPS_PLUGIN)
{
    if(!
iXP)
    {
        return 
0
    
}

    if(
g_eSettings[IGNORE_BOTS] && g_ePlayerData[id][IsBot])
    {
        return 
0
    
}

    if(
iSource == CRXRANKS_XPS_REWARD)
    {
        if(
g_eSettings[MINIMUM_PLAYERS] && get_playersnum() < g_eSettings[MINIMUM_PLAYERS])
        {
            return 
0
        
}

        if(
g_eSettings[TEAM_LOCK] && get_user_team(id) != g_eSettings[TEAM_LOCK])
        {
            return 
0
        
}
    }

    static 
iReturn
    ExecuteForward
(g_fwdUserReceiveXPiReturnidiXPiSource)

    switch(
iReturn)
    {
        case 
CRXRANKS_HANDLED: return 0
        
case CRXRANKS_CONTINUE: { }
        default:
        {
            if(
iReturn != 0)
            {
                
iXP iReturn
            
}
        }
    }

    
g_ePlayerData[id][XP] += iXP

    
if(g_ePlayerData[id][XP] < 0)
    {
        
g_ePlayerData[id][XP] = 0
    
}

    
check_level(idtrue)
    
ExecuteForward(g_fwdUserXPUpdatediReturnidg_ePlayerData[id][XP], iSource)

    if(
g_eSettings[XP_NOTIFIER_ENABLED])
    {
        static 
szKey[32], bool:bPositive
        bPositive 
iXP >= 0

        copy
(szKeycharsmax(szKey), bPositive "CRXRANKS_XP_NOTIFIER_GET" "CRXRANKS_XP_NOTIFIER_LOSE")

        if(
g_eSettings[XP_NOTIFIER_USE_DHUD])
        {
            if(
bPositive)
            {
                
set_dhudmessage(XP_NOTIFIER_PARAMS_GET)
            }
            else
            {
                
set_dhudmessage(XP_NOTIFIER_PARAMS_LOSE)
            }

            
show_dhudmessage(id"%L"idszKeyabs(iXP))
        }
        else
        {
            if(
bPositive)
            {
                
set_hudmessage(XP_NOTIFIER_PARAMS_GET)
            }
            else
            {
                
set_hudmessage(XP_NOTIFIER_PARAMS_LOSE)
            }

            
ShowSyncHudMsg(idg_iObject[OBJ_XP_NOTIFIER], "%L"idszKeyabs(iXP))
        }
    }

    return 
iXP
}

get_user_saveinfo(const idszInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH], const iLen)
{
    switch(
g_eSettings[SAVE_TYPE])
    {
        case 
SAVE_NICKNAME:    get_user_name(idszInfoiLen)
        case 
SAVE_IPget_user_ip(idszInfoiLen1)
        case 
SAVE_STEAMIDget_user_authid(idszInfoiLen)
    }
}

reset_player_stats(const id)
{
    
g_ePlayerData[id][XP] = 0
    g_ePlayerData
[id][Level] = 0
    g_ePlayerData
[id][NextXP] = 0
    g_ePlayerData
[id][Rank][0] = EOS
    g_ePlayerData
[id][NextRank][0] = EOS
    g_ePlayerData
[id][HUDInfo][0] = EOS
    g_ePlayerData
[id][IsOnFinalLevel] = false
    g_ePlayerData
[id][IsVIP] = false
    g_ePlayerData
[id][IsBot] = false
}

switch_to_nvault()
{
    if(
g_eSettings[USE_MYSQL])
    {
        
g_eSettings[USE_MYSQL] = false
        log_amx
("%L"LANG_SERVER"CRXRANKS_MYSQL_FAILED")
    }
}

bool:has_argument(const szMessage[], const szArg[])
{
    return 
contain(szMessageszArg) != -1
}

bool:should_skip(const iNum)
{
    return (
iNum != && !g_eSettings[USE_COMBINED_EVENTS])
}

send_chat_message(const id, const bool:bLog, const szInput[], any:...)
{
    static 
szMessage[192]
    
vformat(szMessagecharsmax(szMessage), szInput4)

    
#if defined USE_CSTRIKE
    
bLog CC_LogMessage(id_szMessage) : CC_SendMessage(idszMessage)
    
#else
    
format(szMessagecharsmax(szMessage), "%s %s"CC_PREFIXszMessage)
    
client_print(idprint_chatszMessage)

    if(
bLog)
    {
        
log_amx(szMessage)
    }
    
#endif
}

update_hudinfo(const id)
{
    if(!
g_eSettings[HUDINFO_ENABLED])
    {
        return
    }

    static 
szMessage[CRXRANKS_MAX_HUDINFO_LENGTH], szPlaceHolder[32], bool:bIsOnFinal

    bIsOnFinal 
g_ePlayerData[id][IsOnFinalLevel]
    
copy(szMessagecharsmax(szMessage), g_eSettings[bIsOnFinal HUDINFO_FORMAT_FINAL HUDINFO_FORMAT])

    if(
has_argument(szMessageARG_CURRENT_XP))
    {
        
num_to_str(g_ePlayerData[id][XP], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_CURRENT_XPszPlaceHolder)
    }

    if(
has_argument(szMessageARG_NEXT_XP))
    {
        
num_to_str(g_ePlayerData[id][NextXP], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NEXT_XPszPlaceHolder)
    }

    if(
has_argument(szMessageARG_XP_NEEDED))
    {
        
num_to_str(g_ePlayerData[id][NextXP] - g_ePlayerData[id][XP], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_XP_NEEDEDszPlaceHolder)
    }

    if(
has_argument(szMessageARG_LEVEL))
    {
        
num_to_str(g_ePlayerData[id][Level], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_LEVELszPlaceHolder)
    }

    if(
has_argument(szMessageARG_NEXT_LEVEL))
    {
        
num_to_str(g_ePlayerData[id][bIsOnFinal Level Level 1], szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NEXT_LEVELszPlaceHolder)
    }

    
replace_string(szMessagecharsmax(szMessage), ARG_MAX_LEVELSg_szMaxLevels)

    if(
has_argument(szMessageARG_NAME))
    {
        
get_user_name(idszPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NAMEszPlaceHolder)
    }

    
replace_string(szMessagecharsmax(szMessage), ARG_RANKg_ePlayerData[id][Rank])
    
replace_string(szMessagecharsmax(szMessage), ARG_NEXT_RANKg_ePlayerData[id][NextRank])
    
replace_string(szMessagecharsmax(szMessage), ARG_LINE_BREAK"^n")
    
copy(g_ePlayerData[id][HUDInfo], charsmax(g_ePlayerData[][HUDInfo]), szMessage)
}

check_level(const id, const bool:bNotify)
{
    static 
iLeveli
    iLevel 
0

    
for(1g_iMaxLevels 1i++)
    {
        if(
g_ePlayerData[id][XP] >= ArrayGetCell(g_aLevelsi))
        {
            
iLevel++
        }
    }

    if(
iLevel != g_ePlayerData[id][Level])
    {
        static 
bool:bLevelUpiReturn
        bLevelUp 
iLevel g_ePlayerData[id][Level]
        
g_ePlayerData[id][Level] = iLevel
        ArrayGetString
(g_aRankNamesiLevelg_ePlayerData[id][Rank], charsmax(g_ePlayerData[][Rank]))

        if(
iLevel g_iMaxLevels)
        {
            
g_ePlayerData[id][IsOnFinalLevel] = false
            g_ePlayerData
[id][NextXP] = ArrayGetCell(g_aLevelsiLevel 1)
            
ArrayGetString(g_aRankNamesiLevel 1g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]))
        }
        else
        {
            
g_ePlayerData[id][IsOnFinalLevel] = true
            g_ePlayerData
[id][NextXP] = ArrayGetCell(g_aLevelsiLevel)
            
copy(g_ePlayerData[id][NextRank], charsmax(g_ePlayerData[][NextRank]), g_eSettings[HUDINFO_INVALID_TEXT])

            if(
g_eSettings[FINAL_LEVEL_FLAGS])
            {
                
set_user_flags(idg_eSettings[FINAL_LEVEL_FLAGS_BIT])
                
remove_user_flags(idg_iFlagZ)
            }
        }

        
ExecuteForward(g_fwdUserLevelUpdatediReturnidiLevelbLevelUp)

        if(
bNotify && g_eSettings[LEVELUP_MESSAGE_TYPE])
        {
            static 
szMessage[128], szName[32], bool:bGlobalMsg
            get_user_name
(idszNamecharsmax(szName))
            
bGlobalMsg g_eSettings[LEVELUP_MESSAGE_TYPE] == 2

            formatex
(szMessagecharsmax(szMessage), "%L"bGlobalMsg LANG_PLAYER id,\
            
bLevelUp "CRXRANKS_LEVEL_REACHED" "CRXRANKS_LEVEL_LOST"szNameg_ePlayerData[id][Level], g_ePlayerData[id][Rank])
            
send_chat_message(bGlobalMsg idfalseszMessage)

            if(
bLevelUp && g_eSettings[LEVELUP_SOUND][0])
            {
                
emit_sound(idCHAN_AUTOg_eSettings[LEVELUP_SOUND], 1.0ATTN_NORM0PITCH_NORM)
            }
            else if(!
bLevelUp && g_eSettings[LEVELDN_SOUND][0])
            {
                
emit_sound(idCHAN_AUTOg_eSettings[LEVELDN_SOUND], 1.0ATTN_NORM0PITCH_NORM)
            }

            if(
g_eSettings[bLevelUp LEVELUP_SCREEN_FADE_ENABLED LEVELDN_SCREEN_FADE_ENABLED])
            {
                
message_begin(MSG_ONEg_iScreenFade, {000}, id)
                
write_short(1<<10)
                
write_short(1<<10)
                
write_short(0x0000)

                if(
bLevelUp)
                {
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][0]))
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][1]))
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][2]))
                    
write_byte(clr(g_eSettings[LEVELUP_SCREEN_FADE_COLOR][3]))
                }
                else
                {
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][0]))
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][1]))
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][2]))
                    
write_byte(clr(g_eSettings[LEVELDN_SCREEN_FADE_COLOR][3]))
                }

                
message_end()
            }
        }
    }

    
update_hudinfo(id)
}

public 
update_vip_status(id)
{
    if(
is_user_connected(id) && g_eSettings[VIP_FLAGS_BIT] != ADMIN_ALL)
    {
        
g_ePlayerData[id][IsVIP] = bool:((get_user_flags(id) & g_eSettings[VIP_FLAGS_BIT]) == g_eSettings[VIP_FLAGS_BIT])
    }
}

public 
plugin_natives()
{
    
register_library("crxranks")
    
register_native("crxranks_get_chat_prefix",         "_crxranks_get_chat_prefix")
    
register_native("crxranks_get_final_flags",         "_crxranks_get_final_flags")
    
register_native("crxranks_get_hudinfo_format",      "_crxranks_get_hudinfo_format")
    
register_native("crxranks_get_max_levels",          "_crxranks_get_max_levels")
    
register_native("crxranks_get_rank_by_level",       "_crxranks_get_rank_by_level")
    
register_native("crxranks_get_save_type",           "_crxranks_get_save_type")
    
register_native("crxranks_get_setting",             "_crxranks_get_setting")
    
register_native("crxranks_get_user_hudinfo",        "_crxranks_get_user_hudinfo")
    
register_native("crxranks_get_user_level",          "_crxranks_get_user_level")
    
register_native("crxranks_get_user_next_rank",      "_crxranks_get_user_next_rank")
    
register_native("crxranks_get_user_next_xp",        "_crxranks_get_user_next_xp")
    
register_native("crxranks_get_user_rank",           "_crxranks_get_user_rank")
    
register_native("crxranks_get_user_xp",             "_crxranks_get_user_xp")
    
register_native("crxranks_get_vault_name",          "_crxranks_get_vault_name")
    
register_native("crxranks_get_vip_flags",           "_crxranks_get_vip_flags")
    
register_native("crxranks_get_xp_for_level",        "_crxranks_get_xp_for_level")
    
register_native("crxranks_get_xp_reward",           "_crxranks_get_xp_reward")
    
register_native("crxranks_give_user_xp",            "_crxranks_give_user_xp")
    
register_native("crxranks_is_hi_using_dhud",        "_crxranks_is_hi_using_dhud")
    
register_native("crxranks_is_hud_enabled",          "_crxranks_is_hud_enabled")
    
register_native("crxranks_is_sfdn_enabled",         "_crxranks_is_sfdn_enabled")
    
register_native("crxranks_is_sfup_enabled",         "_crxranks_is_sfup_enabled")
    
register_native("crxranks_is_user_on_final",        "_crxranks_is_user_on_final")
    
register_native("crxranks_is_user_vip",             "_crxranks_is_user_vip")
    
register_native("crxranks_is_using_mysql",          "_crxranks_is_using_mysql")
    
register_native("crxranks_is_xpn_enabled",          "_crxranks_is_xpn_enabled")
    
register_native("crxranks_is_xpn_using_dhud",       "_crxranks_is_xpn_using_dhud")
    
register_native("crxranks_set_user_xp",             "_crxranks_set_user_xp")
    
register_native("crxranks_using_comb_events",       "_crxranks_using_comb_events")
}

public 
_crxranks_get_chat_prefix(iPluginiParams)
{
    
set_string(1CC_PREFIXget_param(2))
}

public 
_crxranks_get_final_flags(iPluginiParams)
{
    
set_string(1g_eSettings[FINAL_LEVEL_FLAGS], get_param(2))
    return 
g_eSettings[FINAL_LEVEL_FLAGS_BIT]
}

public 
_crxranks_get_hudinfo_format(iPluginiParams)
{
    
set_string(2g_eSettings[get_param(1) ? HUDINFO_FORMAT_FINAL HUDINFO_FORMAT], get_param(3))
}

public 
_crxranks_get_max_levels(iPluginiParams)
{
    return 
g_iMaxLevels
}

public 
_crxranks_get_rank_by_level(iPluginiParams)
{
    static 
iLevel
    iLevel 
get_param(1)

    if(
iLevel || iLevel g_iMaxLevels)
    {
        return 
0
    
}

    static 
szRank[CRXRANKS_MAX_RANK_LENGTH]
    
ArrayGetString(g_aRankNamesiLevelszRankcharsmax(szRank))
    
set_string(2szRankget_param(3))
    return 
1
}

public 
_crxranks_get_save_type(iPluginiParams)
{
    return 
g_eSettings[SAVE_TYPE]
}

public 
bool:_crxranks_get_setting(iPluginiParams)
{
    static 
szKey[MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], bool:bReturn
    get_string
(1szKeycharsmax(szKey))

    
bReturn TrieGetString(g_tSettingsszKeyszValuecharsmax(szValue))
    
set_string(2szValueget_param(3))
    return 
bReturn
}

public 
_crxranks_get_user_hudinfo(iPluginiParams)
{
    
set_string(2g_ePlayerData[get_param(1)][HUDInfo], get_param(3))
}

public 
_crxranks_get_user_level(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][Level]
}

public 
_crxranks_get_user_next_rank(iPluginiParams)
{
    
set_string(2g_ePlayerData[get_param(1)][NextRank], get_param(3))
}

public 
_crxranks_get_user_next_xp(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][NextXP]
}

public 
_crxranks_get_user_rank(iPluginiParams)
{
    
set_string(2g_ePlayerData[get_param(1)][Rank], get_param(3))
}

public 
_crxranks_get_user_xp(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][XP]
}

public 
_crxranks_get_vault_name(iPluginiParams)
{
    
set_string(1g_eSettings[VAULT_NAME], get_param(2))
}

public 
_crxranks_get_vip_flags(iPluginiParams)
{
    
set_string(1g_eSettings[VIP_FLAGS], get_param(2))
    return 
g_eSettings[VIP_FLAGS_BIT]
}

public 
_crxranks_get_xp_for_level(iPluginiParams)
{
    static 
iLevel
    iLevel 
get_param(1)

    if(
iLevel || iLevel g_iMaxLevels)
    {
        return -
1
    
}

    return 
ArrayGetCell(g_aLevelsiLevel)
}

public 
_crxranks_get_xp_reward(iPluginiParams)
{
    static 
szReward[CRXRANKS_MAX_XP_REWARD_LENGTH]
    
get_string(2szRewardcharsmax(szReward))
    return 
get_xp_reward(get_param(1), szReward)
}

public 
_crxranks_give_user_xp(iPluginiParams)
{
    static 
szReward[CRXRANKS_MAX_XP_REWARD_LENGTH], iRewardid

    szReward
[0] = EOS
    id 
get_param(1)
    
get_string(3szRewardcharsmax(szReward))

    if(
szReward[0])
    {
        
iReward get_xp_reward(idszReward)

        if(
iReward)
        {
            
give_user_xp(idiRewardCRXRanks_XPSources:get_param(3))
        }

        return 
iReward
    
}

    
iReward get_param(2)
    
give_user_xp(idiRewardCRXRanks_XPSources:get_param(3))
    return 
iReward
}

public 
bool:_crxranks_is_hi_using_dhud(iPluginiParams)
{
    return 
g_eSettings[HUDINFO_USE_DHUD]
}

public 
bool:_crxranks_is_hud_enabled(iPluginiParams)
{
    return 
g_eSettings[HUDINFO_ENABLED]
}

public 
bool:_crxranks_is_sfdn_enabled(iPluginiParams)
{
    return 
g_eSettings[LEVELDN_SCREEN_FADE_ENABLED]
}

public 
bool:_crxranks_is_sfup_enabled(iPluginiParams)
{
    return 
g_eSettings[LEVELUP_SCREEN_FADE_ENABLED]
}

public 
bool:_crxranks_is_user_on_final(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][IsOnFinalLevel]
}

public 
bool:_crxranks_is_user_vip(iPluginiParams)
{
    return 
g_ePlayerData[get_param(1)][IsVIP]
}

public 
bool:_crxranks_is_using_mysql(iPluginiParams)
{
    return 
g_eSettings[USE_MYSQL]
}

public 
bool:_crxranks_is_xpn_enabled(iPluginiParams)
{
    return 
g_eSettings[XP_NOTIFIER_ENABLED]
}

public 
bool:_crxranks_set_user_xp(iPluginiParams)
{
    static 
idiReturnCRXRanks_XPSources:iSource
    id 
get_param(1)
    
iSource CRXRanks_XPSources:get_param(3)
    
g_ePlayerData[id][XP] = clamp(get_param(2), 0)

    
check_level(idtrue)
    
ExecuteForward(g_fwdUserXPUpdatediReturnidg_ePlayerData[id][XP], iSource)
}

public 
bool:_crxranks_using_comb_events(iPluginiParams)
{
    return 
g_eSettings[USE_COMBINED_EVENTS]
}

public 
bool:_crxranks_is_xpn_using_dhud(iPluginiParams)
{
    return 
g_eSettings[XP_NOTIFIER_USE_DHUD]

@Supergirl - I'm not very sure how exactly that's going to work. Pretty sure a huge portion of the code needs to be completely changed in order to implement such a thing so I don't think it's a good idea from coding perspective.
Fine now. Thanks
LithuanianJack is offline
OciXCrom
Veteran Member
Join Date: Oct 2013
Location: Macedonia
Old 02-10-2019 , 17:10   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #194

Great. Let me know if something isn't working as expected, otherwise I'll use that code in the main post.
__________________
OciXCrom is offline
Send a message via Skype™ to OciXCrom
OciXCrom
Veteran Member
Join Date: Oct 2013
Location: Macedonia
Old 02-16-2019 , 09:53   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #195


  • Fixed MySQL problems (used the same code from above).
  • Added "death" keyword for use in the [XP Rewards] section.
__________________
OciXCrom is offline
Send a message via Skype™ to OciXCrom
Kempa
Junior Member
Join Date: Feb 2019
Old 02-18-2019 , 05:51   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #196

How can i put in ranksystem sma hud options for zombie plague ammo
ex :
ARG_AMMO = "$ammo$"



Code:
/*================================================================================
	
	---------------------------------------
	-*- Zombie Plague 4.3 Includes File -*-
	---------------------------------------
	
	~~~~~~~~~~
	- How To -
	~~~~~~~~~~
	
	To make use of the Zombie Plague API features in your plugin, just
	add the following line at the beginning of your script:
	
	#include <zombieplague>
	
	~~~~~~~~~~~
	- Natives -
	~~~~~~~~~~~
	
	These work just like any other functions: you may have to pass
	parameters and they usually return values.
	
	Example:
	
	if ( is_user_alive( id ) && zp_get_user_zombie( id ) )
	{
		server_print( "Player %d is alive and a zombie", id )
	}
	
	~~~~~~~~~~~~
	- Forwards -
	~~~~~~~~~~~~
	
	Forwards get called whenever an event happens during the game.
	You need to make a public callback somewhere on your script,
	and it will automatically be triggered when the event occurs.
	
	Example:
	
	public zp_user_infected_post( id, infector, nemesis )
	{
		if ( !infector || nemesis )
			return;
		
		server_print( "Player %d just got infected by %d!", id, infector )
	}
	
	Also, take note of cases when there's a suffix:
	
	* _pre  : means the forward will be called BEFORE the event happens
	* _post : means it will be called AFTER the event takes place
	
=================================================================================*/

#if defined _zombieplague_included
  #endinput
#endif
#define _zombieplague_included

/* Teams for zp_register_extra_item() */
#define ZP_TEAM_ZOMBIE (1<<0)
#define ZP_TEAM_HUMAN (1<<1)
#define ZP_TEAM_NEMESIS (1<<2)
#define ZP_TEAM_SURVIVOR (1<<3)

/* Game modes for zp_round_started() */
enum
{
	MODE_INFECTION = 1,
	MODE_NEMESIS,
	MODE_SURVIVOR,
	MODE_SWARM,
	MODE_MULTI,
	MODE_PLAGUE
}

/* Winner teams for zp_round_ended() */
enum
{
	WIN_NO_ONE = 0,
	WIN_ZOMBIES,
	WIN_HUMANS
}

/* Custom forward return values */
#define ZP_PLUGIN_HANDLED 97

/**
 * Returns whether a player is a zombie.
 *
 * @param id		Player index.
 * @return		True if it is, false otherwise.
 */
native zp_get_user_zombie(id)

/**
 * Returns whether a player is a nemesis.
 *
 * @param id		Player index.
 * @return		True if it is, false otherwise.
 */
native zp_get_user_nemesis(id)

/**
 * Returns whether a player is a survivor.
 *
 * @param id		Player index.
 * @return		True if it is, false otherwise.
 */
native zp_get_user_survivor(id)

/**
 * Returns whether a player is the first zombie.
 *
 * @param id		Player index.
 * @return		True if it is, false otherwise.
 */
native zp_get_user_first_zombie(id)

/**
 * Returns whether a player is the last zombie.
 *
 * @param id		Player index.
 * @return		True if it is, false otherwise.
 */
native zp_get_user_last_zombie(id)

/**
 * Returns whether a player is the last human.
 *
 * @param id		Player index.
 * @return		True if it is, false otherwise.
 */
native zp_get_user_last_human(id)

/**
 * Returns a player's current zombie class ID.
 *
 * @param id		Player index.
 * @return		Internal zombie class ID, or -1 if not yet chosen.
 */
native zp_get_user_zombie_class(id)

/**
 * Returns a player's next zombie class ID (for the next infection).
 *
 * @param id		Player index.
 * @return		Internal zombie class ID, or -1 if not yet chosen.
 */
native zp_get_user_next_class(id)

/**
 * Sets a player's next zombie class ID (for the next infection).
 *
 * @param id		Player index.
 * @param classid	A valid zombie class ID.
 * @return		True on success, false otherwise.
 */
native zp_set_user_zombie_class(id, classid)

/**
 * Returns a player's ammo pack count.
 *
 * @param id		Player index.
 * @return		Number of ammo packs owned.
 */
native zp_get_user_ammo_packs(id)

/**
 * Sets a player's ammo pack count.
 *
 * @param id		Player index.
 * @param amount	New quantity of ammo packs owned.
 */
native zp_set_user_ammo_packs(id, amount)

/**
 * Returns the default maximum health of a zombie.
 *
 * Note: Takes into account first zombie's HP multiplier.
 *
 * @param id		Player index.
 * @return		Maximum amount of health points, or -1 if not a normal zombie.
 */
native zp_get_zombie_maxhealth(id)

/**
 * Returns a player's custom flashlight batteries charge.
 *
 * @param id		Player index.
 * @return		Charge percent (0 to 100).
 */
native zp_get_user_batteries(id)

/**
 * Sets a player's custom flashlight batteries charge.
 *
 * @param id		Player index.
 * @param value		New charge percent (0 to 100).
 */
native zp_set_user_batteries(id, charge)

/**
 * Returns whether a player has night vision.
 *
 * @param id		Player index.
 * @return		True if it has, false otherwise.
 */
native zp_get_user_nightvision(id)

/**
 * Sets whether a player has night vision.
 *
 * @param id		Player index.
 * @param set		True to give, false for removing it.
 */
native zp_set_user_nightvision(id, set)

/**
 * Forces a player to become a zombie.
 *
 * Note: Unavailable for last human/survivor.
 *
 * @param id		Player index to be infected.
 * @param infector	Player index who infected him (optional).
 * @param silent	If set, there will be no HUD messages or infection sounds.
 * @param rewards	Whether to show DeathMsg and reward frags, hp, and ammo packs to infector.
 * @return		True on success, false otherwise.
 */
native zp_infect_user(id, infector = 0, silent = 0, rewards = 0)

/**
 * Forces a player to become a human.
 *
 * Note: Unavailable for last zombie/nemesis.
 *
 * @param id		Player index to be cured.
 * @param silent	If set, there will be no HUD messages or antidote sounds.
 * @return		True on success, false otherwise.
 */
native zp_disinfect_user(id, silent = 0)

/**
 * Forces a player to become a nemesis.
 *
 * Note: Unavailable for last human/survivor.
 *
 * @param id		Player index to turn into nemesis.
 * @return		True on success, false otherwise.
 */
native zp_make_user_nemesis(id)

/**
 * Forces a player to become a survivor.
 *
 * Note: Unavailable for last zombie/nemesis.
 *
 * @param id		Player index to turn into survivor.
 * @return		True on success, false otherwise.
 */
native zp_make_user_survivor(id)

/**
 * Respawns a player into a specific team.
 *
 * @param id		Player index to be respawned.
 * @param team		Team to respawn the player into (ZP_TEAM_ZOMBIE or ZP_TEAM_HUMAN).
 * @return		True on success, false otherwise.
 */
native zp_respawn_user(id, team)

/**
 * Forces a player to buy an extra item.
 *
 * @param id		Player index.
 * @param itemid	A valid extra item ID.
 * @param ignorecost	If set, item's cost won't be deduced from player.
 * @return		True on success, false otherwise.
 */
native zp_force_buy_extra_item(id, itemid, ignorecost = 0)

/**
 * Returns whether the ZP round has started, i.e. first zombie
 * has been chosen or a game mode has begun.
 *
 * @return		0 - Round not started
 *			1 - Round started
 *			2 - Round starting
 */
native zp_has_round_started()

/**
 * Returns whether the current round is a nemesis round.
 *
 * @return		True if it is, false otherwise.
 */
native zp_is_nemesis_round()

/**
 * Returns whether the current round is a survivor round.
 *
 * @return		True if it is, false otherwise.
 */
native zp_is_survivor_round()

/**
 * Returns whether the current round is a swarm round.
 *
 * @return		True if it is, false otherwise.
 */
native zp_is_swarm_round()

/**
 * Returns whether the current round is a plague round.
 *
 * @return		True if it is, false otherwise.
 */
native zp_is_plague_round()

/**
 * Returns number of alive zombies.
 *
 * @return		Zombie count.
 */
native zp_get_zombie_count()

/**
 * Returns number of alive humans.
 *
 * @return		Human count.
 */
native zp_get_human_count()

/**
 * Returns number of alive nemesis.
 *
 * @return		Nemesis count.
 */
native zp_get_nemesis_count()

/**
 * Returns number of alive survivors.
 *
 * @return		Survivor count.
 */
native zp_get_survivor_count()

/**
 * Registers a custom item which will be added to the extra items menu of ZP.
 *
 * Note: The returned extra item ID can be later used to catch item
 * purchase events for the zp_extra_item_selected() forward.
 *
 * Note: ZP_TEAM_NEMESIS and ZP_TEAM_SURVIVOR can be used to make
 * an item available to Nemesis and Survivors respectively.
 *
 * @param name		Caption to display on the menu.
 * @param cost		Ammo packs to be deducted on purchase.
 * @param teams		Bitsum of teams it should be available for.
 * @return		An internal extra item ID, or -1 on failure.
 */
native zp_register_extra_item(const name[], cost, teams)

/**
 * Registers a custom class which will be added to the zombie classes menu of ZP.
 *
 * Note: The returned zombie class ID can be later used to identify
 * the class when calling the zp_get_user_zombie_class() natives.
 *
 * @param name		Caption to display on the menu.
 * @param info		Brief description of the class.
 * @param model		Player model to be used.
 * @param clawmodel	Claws model to be used.
 * @param hp		Initial health points.
 * @param speed		Maximum speed.
 * @param gravity	Gravity multiplier.
 * @param knockback	Knockback multiplier.
 * @return		An internal zombie class ID, or -1 on failure.
 */
native zp_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)

/**
 * Returns an extra item's ID.
 *
 * @param name		Item name to look for.
 * @return		Internal extra item ID, or -1 if not found.
 */
native zp_get_extra_item_id(const name[])

/**
 * Returns a zombie class' ID.
 *
 * @param name		Class name to look for.
 * @return		Internal zombie class ID, or -1 if not found.
 */
native zp_get_zombie_class_id(const name[])

/**
 * Called when the ZP round starts, i.e. first zombie
 * is chosen or a game mode begins.
 *
 * @param gamemode	Mode which has started.
 * @param id		Affected player's index (if applicable).
 */
forward zp_round_started(gamemode, id)

/**
 * Called when the round ends.
 *
 * @param winteam	Team which has won the round.
 */
forward zp_round_ended(winteam)

/**
 * Called when a player gets infected.
 *
 * @param id		Player index who was infected.
 * @param infector	Player index who infected him (if applicable).
 * @param nemesis	Whether the player was turned into a nemesis.
 */
forward zp_user_infected_pre(id, infector, nemesis)
forward zp_user_infected_post(id, infector, nemesis)

/**
 * Called when a player turns back to human.
 *
 * @param id		Player index who was cured.
 * @param survivor	Whether the player was turned into a survivor.
 */
forward zp_user_humanized_pre(id, survivor)
forward zp_user_humanized_post(id, survivor)

/**
 * Called on a player infect/cure attempt. You can use this to block
 * an infection/humanization by returning ZP_PLUGIN_HANDLED in your plugin.
 *
 * Note: Right now this is only available after the ZP round starts, since some
 * situations (like blocking a first zombie's infection) are not yet handled.
 */
forward zp_user_infect_attempt(id, infector, nemesis)
forward zp_user_humanize_attempt(id, survivor)

/**
 * Called when a player buys an extra item from the ZP menu.
 *
 * Note: You can now return ZP_PLUGIN_HANDLED in your plugin to block
 * the purchase and the player will be automatically refunded.
 *
 * @param id		Player index of purchaser.
 * @param itemid	Internal extra item ID.
 */
forward zp_extra_item_selected(id, itemid)

/**
 * Called when a player gets unfrozen (frostnades).
 *
 * @param id		Player index.
 */
forward zp_user_unfrozen(id)

/**
 * Called when a player becomes the last zombie.
 *
 * Note: This is called for the first zombie too.
 *
 * @param id		Player index.
 */
forward zp_user_last_zombie(id)

/**
 * Called when a player becomes the last human.
 *
 * @param id		Player index.
 */
forward zp_user_last_human(id)


/**
 * @deprecated - Do not use!
 * For backwards compatibility only.
 */
#define ZP_TEAM_ANY 0
Kempa is offline
OciXCrom
Veteran Member
Join Date: Oct 2013
Location: Macedonia
Old 02-18-2019 , 07:47   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #197

You'll need to edit the plugin since right now there's no way to do it with the API. It's not a very good thing to do because the HUD is only updated when your XP amount changes in order to prevent redundant function calls. This means that the ammo packs number on the HUD won't update until your XP updates. Anyways, if you want to do it, here's how:

1. Add #include <zombie_plague> (or whatever the .inc file name is).
2. Scroll down to lines 47-56 and add new const ARG_ZP_AMMO[] = "$ammo$"
3. Find the update_hudinfo function on line 1354 and after these lines:

PHP Code:
if(has_argument(szMessageARG_NAME))
    {
        
get_user_name(idszPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_NAMEszPlaceHolder)
    } 
Add this:

PHP Code:
if(has_argument(szMessageARG_ZP_AMMO))
    {
        
num_to_str(zp_get_user_ammo_packs(id), szPlaceHoldercharsmax(szPlaceHolder))
        
replace_string(szMessagecharsmax(szMessage), ARG_ZP_AMMOszPlaceHolder)
    } 
If you want to update it in time, you can edit the zombie plague mod as well and make it update the HUD each time you receive/lose ammo packs. If you want to do it, attach the mod's main .sma file.
__________________

Last edited by OciXCrom; 02-18-2019 at 07:47.
OciXCrom is offline
Send a message via Skype™ to OciXCrom
Kempa
Junior Member
Join Date: Feb 2019
Old 02-19-2019 , 05:39   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #198

I'll try, thank you
Kempa is offline
GBLTeam
Senior Member
Join Date: Mar 2012
Location: Republic of Macedonia
Old 02-22-2019 , 17:30   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #199

Is there cmd to reset all ranks or just to delete the file from cstrike/data/ ?

Last edited by GBLTeam; 02-22-2019 at 17:31.
GBLTeam is offline
Send a message via MSN to GBLTeam Send a message via Skype™ to GBLTeam
OciXCrom
Veteran Member
Join Date: Oct 2013
Location: Macedonia
Old 02-22-2019 , 18:23   Re: OciXCrom's Rank System [XP|Levels|Ranks]
Reply With Quote #200

Simply change the file name from RankSystem.ini. Adding a command for this is rather dangerous.
__________________
OciXCrom is offline
Send a message via Skype™ to OciXCrom
Reply


Thread Tools
Display Modes

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 21:47.


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