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

Одобрените от нас плъгини. Моля, докладвайте ако забележите бъг с някой от плъгините в този раздел.
Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

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

Мнение от OciXCrom » 28 Юни 2020, 15:45

Кое не можеш да намериш? Всичко си е качено в архива. Щом пише, че файлът липсва, значи не си го добавил!

Ако си изтеглил готов мод от цс-хлапе, трий го и изтегли си чист АМХХ от официалния уебсайт ако не искаш да получаваш такива смешни грешки.

Аватар
balaghan
Извън линия
Потребител
Потребител
Мнения: 1
Регистриран на: 28 Юни 2020, 19:15

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

Мнение от balaghan » 28 Юни 2020, 21:40

Работи чудесно. Благодаря !

Аватар
Buzdrev
Извън линия
Потребител
Потребител
Мнения: 247
Регистриран на: 12 Окт 2016, 16:45
Се отблагодари: 5 пъти
Получена благодарност: 1 път
Обратна връзка:

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

Мнение от Buzdrev » 07 Юли 2020, 23:22

Възможно ли е да направиш преработка на плъгина като го свържеш с твоя плъгин за AdminGroups, идеята ми е в hud-a на този плъгин да добавя: Rang: $admingroup$ (това да е администраторския ранг на играча, който се извиква от плъгина AdminGroups)

Аватар
gadinkata
Извън линия
Потребител
Потребител
Мнения: 259
Регистриран на: 21 Мар 2018, 12:33
Местоположение: Враца
Се отблагодари: 25 пъти
Получена благодарност: 7 пъти
Обратна връзка:

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

Мнение от gadinkata » 24 Сеп 2020, 20:11

#include <agroups>Трябва да си добавиш agroups.inc в include папката за да се компилира
HUDINFO_FORMAT = [ XP: $current_xp$/$next_xp$ | Level $level$/$max_levels$: $rank$ |Groups: $groups$] едитваш си този ред в RankSistem.ini
Добавил съм 4 реда код...

Код за потвърждение: Избери целия код

#include <agroups>

new const ARG_GROUPS[]	= "$groups$"

public client_putinserver(id)
{
update_hudinfo(id)
}

if(has_argument(szMessage, ARG_GROUPS))
{
agroups_get_user_group(id, szPlaceHolder, charsmax(szPlaceHolder))
replace_string(szMessage, charsmax(szMessage), ARG_GROUPS, szPlaceHolder)
}
Ето и целия код.

Код за потвърждение: Избери целия код

#include <amxmodx>
#include <amxmisc>
#include <cromchat>
#include <crxranks_const>
#include <csx>
#include <fakemeta>
#include <nvault>
#include <sqlx>
#include <agroups>

#if AMXX_VERSION_NUM < 183 || !defined set_dhudmessage
	#tryinclude <dhudmessage>

	#if !defined _dhudmessage_included
		#error "dhudmessage.inc" is missing in your "scripting/include" folder. Download it from: "https://amxx-bg.info/forum/inc/"
	#endif
#endif

#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.9"
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 MAX_TEAM_LENGTH = 10
const TASK_HUD = 304500

#if !defined MAX_NAME_LENGTH
const MAX_NAME_LENGTH = 32
#endif

#if !defined MAX_PLAYERS
const MAX_PLAYERS = 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 ARG_GROUPS[]				= "$groups$"

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

new const XPREWARD_BOMB_PLANTED[]   = "bomb_planted"
new const XPREWARD_BOMB_DEFUSED[]   = "bomb_defused"
new const XPREWARD_BOMB_EXPLODED[]  = "bomb_exploded"

new const XPREWARD_TEAM_WIN[]       = "team_win"
new const XPREWARD_TEAM_LOSE[]      = "team_lose"
new const XPREWARD_TEAM_WIN_CT[]    = "team_win_ct"
new const XPREWARD_TEAM_WIN_T[]     = "team_win_t"
new const XPREWARD_TEAM_LOSE_CT[]   = "team_lose_ct"
new const XPREWARD_TEAM_LOSE_T[]    = "team_lose_t"

#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], 0, 0.1, 1.0, 0.1, 0.1

#define HUDINFO_PARAMS_DEAD clr(g_eSettings[HUDINFO_COLOR][0]), clr(g_eSettings[HUDINFO_COLOR][1]), clr(g_eSettings[HUDINFO_COLOR][2]),\
g_eSettings[HUDINFO_POSITION_DEAD][0], g_eSettings[HUDINFO_POSITION_DEAD][1], 0, 0.1, 1.0, 0.1, 0.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 _:SaveInterval
{
	SAVE_ON_DISCONNECT,
	SAVE_ON_DEATH,
	SAVE_ON_ROUND_END,
	SAVE_ON_XP_CHANGE
}

enum _:SaveMethods
{
	SAVE_NVAULT,
	SAVE_MYSQL
}

enum _:HUDInfoVisibility
{
	VIS_ALL_PLAYERS,
	VIS_ONLY_ALIVE,
	VIS_ONLY_DEAD,
	VIS_DEAD_FREEZE_TIME
}

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],
	SaveInfo[CRXRANKS_MAX_PLAYER_INFO_LENGTH],
	bool:HudInfoEnabled,
	bool:IsOnFinalLevel,
	bool:IsVIP,
	bool:IsBot
}

enum _:Settings
{
	SAVE_TYPE,
	SAVE_INTERVAL,
	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[MAX_NAME_LENGTH],
	FINAL_LEVEL_FLAGS_BIT,
	VIP_FLAGS[MAX_NAME_LENGTH],
	VIP_FLAGS_BIT,
	VAULT_NAME[MAX_NAME_LENGTH],
	TEAM_LOCK,
	MINIMUM_PLAYERS,
	bool:IGNORE_BOTS,
	bool:USE_COMBINED_EVENTS,
	bool:NOTIFY_ON_KILL,
	bool:HUDINFO_ENABLED,
	HUDINFO_VISIBILITY,
	bool:HUDINFO_TEAM_LOCK,
	bool:HUDINFO_OTHER_PLAYERS,
	HUDINFO_COLOR[3],
	Float:HUDINFO_POSITION[2],
	Float:HUDINFO_POSITION_DEAD[2],
	bool:HUDINFO_USE_DHUD,
	HUDINFO_FORMAT[CRXRANKS_MAX_HUDINFO_LENGTH],
	HUDINFO_FORMAT_FINAL[CRXRANKS_MAX_HUDINFO_LENGTH],
	HUDINFO_INVALID_TEXT[MAX_NAME_LENGTH],
	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[MAX_PLAYERS + 1][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 bool:g_bIsCstrike
new bool:g_bFreezeTime

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
new g_fwdUserNameChanged

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

	register_dictionary(g_bIsCstrike ? "RankSystem.txt" : "RankSystemNoColors.txt")

	register_event("DeathMsg", "OnPlayerKilled", "a")
	register_event("SayText", "OnSayText", "a", "2=#Cstrike_Name_Change")

	if(g_eSettings[HUDINFO_VISIBILITY] == VIS_DEAD_FREEZE_TIME)
	{
		register_event("HLTV", "OnFreezeTimeStart", "a", "1=0", "2=0")
		register_logevent("OnRoundStart", 2, "1=Round_Start")
	}

	if(g_eSettings[SAVE_INTERVAL] == SAVE_ON_ROUND_END)
	{
		register_logevent("OnRoundEnd", 2, "1=Round_End")
	}

	if(g_bIsCstrike)
	{
		register_event("SendAudio", "OnTeamWin", "a", "2&%!MRAD_terwin", "2&%!MRAD_ctwin")
	}

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

	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_IGNORE, FP_CELL, FP_CELL, FP_CELL)
	g_fwdUserReceiveXP    = CreateMultiForward("crxranks_user_receive_xp",    ET_STOP,   FP_CELL, FP_CELL, FP_CELL)
	g_fwdUserXPUpdated    = CreateMultiForward("crxranks_user_xp_updated",    ET_IGNORE, FP_CELL, FP_CELL, FP_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 iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))

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

		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_LENGTH, CRXRANKS_MAX_XP_LENGTH, CRXRANKS_MAX_XP_LENGTH, CRXRANKS_MAX_XP_LENGTH,\
		MAX_SQL_RANK_LENGTH, MAX_SQL_RANK_LENGTH)

		if(!SQL_Execute(iQueries))
		{
			SQL_QueryError(iQueries, g_szSqlError, charsmax(g_szSqlError))
			log_amx(g_szSqlError)
			switch_to_nvault()
		}

		SQL_FreeHandle(iQueries)

		@FREE_SQL_CONNECTION:
		SQL_FreeHandle(iSqlConnection)
	}

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

public plugin_precache()
{
	new szModname[MAX_NAME_LENGTH]
	get_modname(szModname, charsmax(szModname))

	if(equal(szModname, "cstrike"))
	{
		g_bIsCstrike = true
	}

	g_aLevels = ArrayCreate(1)
	ArrayPushCell(g_aLevels, 0)

	g_aRankNames = ArrayCreate(MAX_NAME_LENGTH)
	ArrayPushString(g_aRankNames, "")

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

	ReadFile()
}

public plugin_cfg()
{
	if(g_eSettings[HUDINFO_VISIBILITY] == VIS_DEAD_FREEZE_TIME && get_cvar_num("mp_freezetime"))
	{
		g_bFreezeTime = true
	}
}

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])
	{
		SQL_FreeHandle(g_iSqlTuple)
	}
	else
	{
		nvault_close(g_iVault)
	}
}

ReadFile()
{
	new szFilename[256]
	get_configsdir(szFilename, charsmax(szFilename))
	add(szFilename, charsmax(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 = true, bool:bHasDeadPosition, i, iSize, iSection = SECTION_NONE
		get_mapname(szMap, charsmax(szMap))

		while(!feof(iFilePointer))
		{
			fgets(iFilePointer, szData, charsmax(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(szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '*')
							copy(szValue, strlen(szKey), szMap)
							bRead = equal(szValue, szKey) ? true : false
						}
						else
						{
							static const szAll[] = "#all"
							bRead = equal(szData, szAll) || equali(szData, szMap)
						}
					}
					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(szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '=')
					trim(szKey); trim(szValue)

					switch(iSection)
					{
						case SECTION_SETTINGS:
						{
							TrieSetString(g_tSettings, szKey, szValue)

							if(equal(szKey, "CHAT_PREFIX"))
							{
								if(g_bIsCstrike)
								{
									CC_SetPrefix(szValue)
								}
								else
								{
									copy(CC_PREFIX, charsmax(CC_PREFIX), szValue)
								}
							}
							else if(equal(szKey, "SAVE_TYPE"))
							{
								g_eSettings[SAVE_TYPE] = clamp(str_to_num(szValue), SAVE_NICKNAME, SAVE_STEAMID)
							}
							else if(equal(szKey, "SAVE_INTERVAL"))
							{
								g_eSettings[SAVE_INTERVAL] = clamp(str_to_num(szValue), SAVE_ON_DISCONNECT, SAVE_ON_XP_CHANGE)
							}
							else if(equal(szKey, "USE_MYSQL"))
							{
								g_eSettings[USE_MYSQL] = _:clamp(str_to_num(szValue), false, true)
							}
							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] != 0 && strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(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), 0, 2)
							}
							else if(equal(szKey, "LEVELUP_SOUND"))
							{
								copy(g_eSettings[LEVELUP_SOUND], charsmax(g_eSettings[LEVELUP_SOUND]), szValue)

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

								for(i = 0; i < 4; i++)
								{
									g_eSettings[LEVELUP_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1, 255)
								}
							}
							else if(equal(szKey, "LEVELDN_SOUND"))
							{
								copy(g_eSettings[LEVELDN_SOUND], charsmax(g_eSettings[LEVELDN_SOUND]), szValue)

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

								for(i = 0; i < 4; i++)
								{
									g_eSettings[LEVELDN_SCREEN_FADE_COLOR][i] = clamp(str_to_num(szTemp[i]), -1, 255)
								}
							}
							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), 0, 32)
							}
							else if(equal(szKey, "IGNORE_BOTS"))
							{
								g_eSettings[IGNORE_BOTS] = _:clamp(str_to_num(szValue), false, true)
							}
							else if(equal(szKey, "USE_COMBINED_EVENTS"))
							{
								g_eSettings[USE_COMBINED_EVENTS] = _:clamp(str_to_num(szValue), false, true)
							}
							else if(equal(szKey, "NOTIFY_ON_KILL"))
							{
								g_eSettings[NOTIFY_ON_KILL] = _:clamp(str_to_num(szValue), false, true)
							}
							else if(equal(szKey, "HUDINFO_ENABLED"))
							{
								g_eSettings[HUDINFO_ENABLED] = _:clamp(str_to_num(szValue), false, true)
							}
							else if(equal(szKey, "HUDINFO_VISIBILITY") || equal(szKey, "HUDINFO_ALIVE_ONLY") /* changed in v3.9 */ )
							{
								g_eSettings[HUDINFO_VISIBILITY] = clamp(str_to_num(szValue), VIS_ALL_PLAYERS, VIS_DEAD_FREEZE_TIME)
							}
							else if(equal(szKey, "HUDINFO_TEAM_LOCK"))
							{
								g_eSettings[HUDINFO_TEAM_LOCK] = _:clamp(str_to_num(szValue), false, true)
							}
							else if(equal(szKey, "HUDINFO_OTHER_PLAYERS"))
							{
								g_eSettings[HUDINFO_OTHER_PLAYERS] = _:clamp(str_to_num(szValue), false, true)
							}
							else if(equal(szKey, "HUDINFO_COLOR"))
							{
								parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

								for(i = 0; i < 3; i++)
								{
									g_eSettings[HUDINFO_COLOR][i] = clamp(str_to_num(szTemp[i]), -1, 255)
								}
							}
							else if(equal(szKey, "HUDINFO_POSITION"))
							{
								parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

								for(i = 0; i < 2; i++)
								{
									g_eSettings[HUDINFO_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.0, 1.0)
								}
							}
							else if(equal(szKey, "HUDINFO_POSITION_DEAD"))
							{
								bHasDeadPosition = true
								parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

								for(i = 0; i < 2; i++)
								{
									g_eSettings[HUDINFO_POSITION_DEAD][i] = _:floatclamp(str_to_float(szTemp[i]), -1.0, 1.0)
								}
							}
							else if(equal(szKey, "HUDINFO_USE_DHUD"))
							{
								g_eSettings[HUDINFO_USE_DHUD] = _:clamp(str_to_num(szValue), false, true)

								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), false, true)
							}
							else if(equal(szKey, "XP_NOTIFIER_COLOR_GET"))
							{
								parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

								for(i = 0; i < 3; i++)
								{
									g_eSettings[XP_NOTIFIER_COLOR_GET][i] = clamp(str_to_num(szTemp[i]), -1, 255)
								}
							}
							else if(equal(szKey, "XP_NOTIFIER_COLOR_LOSE"))
							{
								parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]), szTemp[2], charsmax(szTemp[]))

								for(i = 0; i < 3; i++)
								{
									g_eSettings[XP_NOTIFIER_COLOR_LOSE][i] = clamp(str_to_num(szTemp[i]), -1, 255)
								}
							}
							else if(equal(szKey, "XP_NOTIFIER_POSITION"))
							{
								parse(szValue, szTemp[0], charsmax(szTemp[]), szTemp[1], charsmax(szTemp[]))

								for(i = 0; i < 2; i++)
								{
									g_eSettings[XP_NOTIFIER_POSITION][i] = _:floatclamp(str_to_float(szTemp[i]), -1.0, 1.0)
								}
							}
							else if(equal(szKey, "XP_NOTIFIER_DURATION"))
							{
								g_eSettings[XP_NOTIFIER_DURATION] = _:floatclamp(str_to_float(szValue), 0.0, float(cellmax))
							}
							else if(equal(szKey, "XP_NOTIFIER_USE_DHUD"))
							{
								g_eSettings[XP_NOTIFIER_USE_DHUD] = _:clamp(str_to_num(szValue), false, true)

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

							parse(szValue, szReward[0], charsmax(szReward[]), szReward[1], charsmax(szReward[]))
							TrieSetCell(g_tXPRewards, szKey, str_to_num(szReward[0]))

							if(szReward[1][0])
							{
								TrieSetCell(g_tXPRewardsVIP, szKey, str_to_num(szReward[1]))
							}
						}
					}
				}
			}
		}

		if(!bHasDeadPosition)
		{
			for(i = 0; i < 2; i++)
			{
				g_eSettings[HUDINFO_POSITION_DEAD][i] = _:g_eSettings[HUDINFO_POSITION][i]
			}
		}

		num_to_str(g_iMaxLevels, g_szMaxLevels, charsmax(g_szMaxLevels))
		fclose(iFilePointer)
	}
}

public client_connect(id)
{
	reset_player_stats(id)

	switch(g_eSettings[SAVE_TYPE])
	{
		case SAVE_NICKNAME: get_user_name(id, g_ePlayerData[id][SaveInfo], charsmax(g_ePlayerData[][SaveInfo]))
		case SAVE_IP:       get_user_ip(id, g_ePlayerData[id][SaveInfo], charsmax(g_ePlayerData[][SaveInfo]), 1)
		case SAVE_STEAMID:  get_user_authid(id, g_ePlayerData[id][SaveInfo], charsmax(g_ePlayerData[][SaveInfo]))
	}

	save_or_load(id, g_ePlayerData[id][SaveInfo], SL_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_putinserver(id)
{
	update_hudinfo(id)
}

public client_disconnected(id)
{
	if(g_eSettings[SAVE_INTERVAL] != SAVE_ON_XP_CHANGE)
	{
		save_or_load(id, g_ePlayerData[id][SaveInfo], SL_SAVE_DATA)
	}

	remove_task(id + TASK_HUD)
}

public OnSayText(iMsg, iDestination, iEntity)
{
	g_fwdUserNameChanged = register_forward(FM_ClientUserInfoChanged, "OnNameChange", 1)
}

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

	new szName[MAX_NAME_LENGTH]
	get_user_name(id, szName, charsmax(szName))

	if(g_eSettings[SAVE_TYPE] == SAVE_NICKNAME)
	{
		save_or_load(id, g_ePlayerData[id][SaveInfo], SL_SAVE_DATA)
		copy(g_ePlayerData[id][SaveInfo], charsmax(g_ePlayerData[][SaveInfo]), szName)

		if(g_eSettings[USE_MYSQL])
		{
			reset_player_stats(id)
		}

		save_or_load(id, szName, SL_LOAD_DATA)
		update_hudinfo(id)
	}

	update_vip_status(id)
	unregister_forward(FM_ClientUserInfoChanged, g_fwdUserNameChanged, 1)
}

public DisplayHUD(id)
{
	id -= TASK_HUD

	if(!g_ePlayerData[id][HudInfoEnabled])
	{
		return
	}

	new bool:bIsAlive, iTarget

	bIsAlive = is_user_alive(id) != 0
	iTarget = id

	if(bIsAlive)
	{
		switch(g_eSettings[HUDINFO_VISIBILITY])
		{
			case VIS_ONLY_DEAD: return
			case VIS_DEAD_FREEZE_TIME:
			{
				if(!g_bFreezeTime)
				{
					return
				}
			}
		}
	}
	else
	{
		if(g_eSettings[HUDINFO_VISIBILITY] == VIS_ONLY_ALIVE)
		{
			return
		}

		if(g_eSettings[HUDINFO_OTHER_PLAYERS])
		{
			iTarget = pev(id, pev_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])
	{
		if(bIsAlive)
		{
			set_dhudmessage(HUDINFO_PARAMS)
		}
		else
		{
			set_dhudmessage(HUDINFO_PARAMS_DEAD)
		}

		show_dhudmessage(id, g_ePlayerData[iTarget][HUDInfo])
	}
	else
	{
		if(bIsAlive)
		{
			set_hudmessage(HUDINFO_PARAMS)
		}
		else
		{
			set_hudmessage(HUDINFO_PARAMS_DEAD)
		}

		ShowSyncHudMsg(id, g_iObject[OBJ_HUDINFO], g_ePlayerData[iTarget][HUDInfo])
	}
}

public bomb_planted(id)
{
	give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_PLANTED), CRXRANKS_XPS_REWARD)
}

public bomb_defused(id)
{
	give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_DEFUSED), CRXRANKS_XPS_REWARD)
}

public bomb_explode(id)
{
	give_user_xp(id, get_xp_reward(id, XPREWARD_BOMB_EXPLODED), CRXRANKS_XPS_REWARD)
}

public Cmd_XP(id)
{
	if(g_ePlayerData[id][Level] == g_iMaxLevels)
	{
		send_chat_message(id, false, "%L", id, "CRXRANKS_RANKINFO_FINAL", g_ePlayerData[id][XP], g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
	}
	else
	{
		send_chat_message(id, false, "%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(id, iLevel, iCid)
{
	if(!cmd_access(id, iLevel, iCid, 1))
	{
		return PLUGIN_HANDLED
	}

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

	new iPlayers[MAX_PLAYERS], iPnum, iMenu = menu_create(szTitle, "XPList_Handler")
	get_players(iPlayers, iPnum); SortCustom1D(iPlayers, iPnum, "sort_players_by_xp")

	for(new szItem[128], szName[MAX_NAME_LENGTH], iPlayer, i; i < iPnum; i++)
	{
		iPlayer = iPlayers[i]
		get_user_name(iPlayer, szName, charsmax(szName))
		formatex(szItem, charsmax(szItem), "%L", id, "CRXRANKS_ITEM_FORMAT", g_ePlayerData[iPlayer][XP], szName, g_ePlayerData[iPlayer][Level], g_ePlayerData[iPlayer][Rank])
		menu_additem(iMenu, szItem)
	}

	menu_display(id, iMenu)
	return PLUGIN_HANDLED
}

public Cmd_HudInfo(id, iLevel, iCid)
{
	if(!cmd_access(id, iLevel, iCid, 1))
	{
		return PLUGIN_HANDLED
	}

	if(!g_eSettings[HUDINFO_ENABLED])
	{
		send_chat_message(id, false, "%L", id, "CRXRANKS_HUDINFO_UNAVAILABLE")
		return PLUGIN_HANDLED
	}

	g_ePlayerData[id][HudInfoEnabled] = !g_ePlayerData[id][HudInfoEnabled]
	send_chat_message(id, false, "%L", id, g_ePlayerData[id][HudInfoEnabled] ? "CRXRANKS_HUDINFO_ENABLED" : "CRXRANKS_HUDINFO_DISABLED")
	return PLUGIN_HANDLED
}

public XPList_Handler(id, iMenu, iItem)
{
	menu_destroy(iMenu)
	return PLUGIN_HANDLED
}

public Cmd_GiveXP(id, iLevel, iCid)
{
	if(!cmd_access(id, iLevel, iCid, 3))
	{
		return PLUGIN_HANDLED
	}

	new szPlayer[MAX_NAME_LENGTH]
	read_argv(1, szPlayer, charsmax(szPlayer))

	new iPlayer = cmd_target(id, szPlayer, 0)

	if(!iPlayer)
	{
		return PLUGIN_HANDLED
	}

	new szName[2][MAX_NAME_LENGTH], szAmount[CRXRANKS_MAX_XP_LENGTH]
	read_argv(2, szAmount, charsmax(szAmount))
	get_user_name(id, szName[0], charsmax(szName[]))
	get_user_name(iPlayer, szName[1], charsmax(szName[]))

	new szKey[MAX_NAME_LENGTH], iXP = str_to_num(szAmount)
	give_user_xp(iPlayer, iXP, CRXRANKS_XPS_ADMIN)

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

	send_chat_message(0, true, "%L", id, szKey, szName[0], iXP, szName[1])
	return PLUGIN_HANDLED
}

public Cmd_ResetXP(id, iLevel, iCid)
{
	if(!cmd_access(id, iLevel, iCid, 2))
	{
		return PLUGIN_HANDLED
	}

	new szPlayer[MAX_NAME_LENGTH]
	read_argv(1, szPlayer, charsmax(szPlayer))

	new iPlayer = cmd_target(id, szPlayer, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF)

	if(!iPlayer)
	{
		return PLUGIN_HANDLED
	}

	new szName[2][MAX_NAME_LENGTH]
	get_user_name(id, szName[0], charsmax(szName[]))
	get_user_name(iPlayer, szName[1], charsmax(szName[]))

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

	if(g_eSettings[SAVE_INTERVAL] == SAVE_ON_XP_CHANGE)
	{
		save_or_load(iPlayer, g_ePlayerData[iPlayer][SaveInfo], SL_SAVE_DATA)
	}

	return PLUGIN_HANDLED
}

public OnFreezeTimeStart()
{
	g_bFreezeTime = true
}

public OnRoundStart()
{
	g_bFreezeTime = false
}

public OnRoundEnd()
{
	new iPlayers[32], iPnum
	get_players(iPlayers, iPnum)

	for(new i, iPlayer; i < iPnum; i++)
	{
		iPlayer = iPlayers[i]
		save_or_load(iPlayer, g_ePlayerData[iPlayer][SaveInfo], SL_SAVE_DATA)
	}
}

public OnTeamWin()
{
	new szTeam[MAX_TEAM_LENGTH], szWinTeam[MAX_TEAM_LENGTH], szLoseTeam[MAX_TEAM_LENGTH]
	read_data(2, szTeam, charsmax(szTeam))
	copy(szWinTeam, charsmax(szWinTeam),   szTeam[7] == 'c' ? "CT" : "TERRORIST")
	copy(szLoseTeam, charsmax(szLoseTeam), szTeam[7] == 'c' ? "TERRORIST" : "CT")

	if(xp_reward_is_set(XPREWARD_TEAM_WIN))
	{
		reward_team(szWinTeam, XPREWARD_TEAM_WIN)
	}

	if(xp_reward_is_set(XPREWARD_TEAM_LOSE))
	{
		reward_team(szLoseTeam, XPREWARD_TEAM_LOSE)
	}

	if(szWinTeam[0] == 'C')
	{
		if(xp_reward_is_set(XPREWARD_TEAM_WIN_CT))
		{
			reward_team(szWinTeam, XPREWARD_TEAM_WIN_CT)
		}

		if(xp_reward_is_set(XPREWARD_TEAM_LOSE_T))
		{
			reward_team(szLoseTeam, XPREWARD_TEAM_LOSE_T)
		}
	}
	else
	{
		if(xp_reward_is_set(XPREWARD_TEAM_WIN_T))
		{
			reward_team(szWinTeam, XPREWARD_TEAM_WIN_T)
		}

		if(xp_reward_is_set(XPREWARD_TEAM_LOSE_CT))
		{
			reward_team(szLoseTeam, XPREWARD_TEAM_LOSE_CT)
		}
	}
}

public OnPlayerKilled()
{
	new szWeapon[16], iAttacker = read_data(1), iVictim = read_data(2), iXP
	read_data(4, szWeapon, charsmax(szWeapon))

	if(!is_user_connected(iVictim))
	{
		return
	}

	if(g_eSettings[SAVE_INTERVAL] == SAVE_ON_DEATH)
	{
		save_or_load(iVictim, g_ePlayerData[iVictim][SaveInfo], SL_SAVE_DATA)
	}

	if(iAttacker == iVictim || equal(szWeapon, "worldspawn") || equal(szWeapon, "door", 4) || equal(szWeapon, "trigger_hurt"))
	{
		iXP = get_xp_reward(iVictim, XPREWARD_SUICIDE)

		if(g_eSettings[USE_COMBINED_EVENTS])
		{
			iXP += get_xp_reward(iVictim, XPREWARD_DEATH)
		}

		give_user_xp(iVictim, iXP, CRXRANKS_XPS_REWARD)

		if(should_send_kill_message(iXP))
		{
			send_chat_message(iVictim, false, "%L", iVictim, iXP > 0 ? "CRXRANKS_NOTIFY_SUICIDE_GET" : "CRXRANKS_NOTIFY_SUICIDE_LOSE", abs(iXP))
		}

		return
	}

	if(!is_user_connected(iAttacker))
	{
		return
	}

	new iReward, iTemp

	if(iAttacker == iVictim)
	{
		iTemp = get_xp_reward(iAttacker, XPREWARD_SUICIDE)
		iReward += iTemp

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

		if(should_skip(iTemp))
		{
			goto @GIVE_REWARD
		}
	}
	else
	{
		iTemp = get_xp_reward(iAttacker, szWeapon)
		iReward += iTemp

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

		if(read_data(3))
		{
			iTemp = get_xp_reward(iAttacker, XPREWARD_HEADSHOT)
			iReward += iTemp

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

		iReward += get_xp_reward(iAttacker, XPREWARD_KILL)
	}

	@GIVE_REWARD:
	iXP = give_user_xp(iAttacker, iReward, CRXRANKS_XPS_REWARD)

	if(should_send_kill_message(iXP))
	{
		new szName[MAX_NAME_LENGTH]
		get_user_name(iVictim, szName, charsmax(szName))
		send_chat_message(iAttacker, false, "%L", iAttacker, iXP > 0 ? "CRXRANKS_NOTIFY_KILL_GET" : "CRXRANKS_NOTIFY_KILL_LOSE", abs(iXP), szName)
	}

	iXP = give_user_xp(iVictim, get_xp_reward(iVictim, XPREWARD_DEATH), CRXRANKS_XPS_REWARD)

	if(should_send_kill_message(iXP))
	{
		send_chat_message(iVictim, false, "%L", iVictim, iXP > 0 ? "CRXRANKS_NOTIFY_DEATH_GET" : "CRXRANKS_NOTIFY_DEATH_LOSE", abs(iXP))
	}
}

public sort_players_by_xp(id1, id2)
{
	return g_ePlayerData[id2][XP] - g_ePlayerData[id1][XP]
}

public QueryHandler(iFailState, Handle:iQuery, szError[], iErrorCode)
{
	switch(iFailState)
	{
		case TQUERY_CONNECT_FAILED: log_amx("[SQL Error] Connection failed (%i): %s", iErrorCode, szError)
		case TQUERY_QUERY_FAILED:   log_amx("[SQL Error] Query failed (%i): %s", iErrorCode, szError)
	}
}

bool:xp_reward_is_set(const szReward[])
{
	return TrieKeyExists(g_tXPRewards, szReward)
}

reward_team(const szTeam[], const szReward[])
{
	new iPlayers[MAX_PLAYERS], iPnum
	get_players(iPlayers, iPnum, "e", szTeam)

	for(new i, iPlayer; i < iPnum; i++)
	{
		iPlayer = iPlayers[i]
		give_user_xp(iPlayer, get_xp_reward(iPlayer, szReward), CRXRANKS_XPS_REWARD)
	}
}

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

	switch(iType)
	{
		case SL_SAVE_DATA:
		{
			if(g_eSettings[USE_MYSQL])
			{
				new szQuery[MAX_QUERY_LENGTH], szPlayer[MAX_SQL_PLAYER_LENGTH], szRank[MAX_SQL_RANK_LENGTH], szNextRank[MAX_SQL_RANK_LENGTH]
				new iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))

				SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)
				SQL_QuoteString(iSqlConnection, szRank, charsmax(szRank), g_ePlayerData[id][Rank])
				SQL_QuoteString(iSqlConnection, szNextRank, charsmax(szNextRank), g_ePlayerData[id][NextRank])

				formatex(szQuery, charsmax(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], szRank, szNextRank, szPlayer)
				SQL_ThreadQuery(g_iSqlTuple, "QueryHandler", szQuery)
				SQL_FreeHandle(iSqlConnection)
			}
			else
			{
				new szData[CRXRANKS_MAX_XP_LENGTH]
				num_to_str(g_ePlayerData[id][XP], szData, charsmax(szData))
				nvault_set(g_iVault, szInfo, szData)
			}
		}
		case SL_LOAD_DATA:
		{
			if(g_eSettings[USE_MYSQL])
			{
				new szPlayer[MAX_SQL_PLAYER_LENGTH], iErrorCode, Handle:iSqlConnection = SQL_Connect(g_iSqlTuple, iErrorCode, g_szSqlError, charsmax(g_szSqlError))
				SQL_QuoteString(iSqlConnection, szPlayer, charsmax(szPlayer), szInfo)

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

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

				if(!SQL_Execute(iQuery))
				{
					SQL_QueryError(iQuery, g_szSqlError, charsmax(g_szSqlError))
					log_amx(g_szSqlError)
					goto @FREE_QUERY
				}

				new bool:bNewPlayer = SQL_NumResults(iQuery) > 0 ? false : true
				SQL_FreeHandle(iQuery)

				new szQuery[MAX_QUERY_LENGTH]

				if(bNewPlayer)
				{
					formatex(szQuery, charsmax(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(szQuery, charsmax(szQuery), "SELECT XP FROM %s WHERE Player = '%s';", g_eSettings[SQL_TABLE], szPlayer)
				}

				iQuery = SQL_PrepareQuery(iSqlConnection, szQuery)

				if(!SQL_Execute(iQuery))
				{
					SQL_QueryError(iQuery, g_szSqlError, charsmax(g_szSqlError))
					log_amx(g_szSqlError)
					goto @CHECK_LEVEL
				}

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

				@CHECK_LEVEL:
				check_level(id, false)

				@FREE_QUERY:
				SQL_FreeHandle(iQuery)

				@FREE_SQL_CONNECTION:
				SQL_FreeHandle(iSqlConnection)
			}
			else
			{
				new iData = nvault_get(g_iVault, szInfo)
				g_ePlayerData[id][XP] = iData ? clamp(iData, 0) : 0
				check_level(id, false)
			}
		}
	}
}

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

	if(g_ePlayerData[id][IsVIP])
	{
		if(TrieKeyExists(g_tXPRewardsVIP, szKey))
		{
			TrieGetCell(g_tXPRewardsVIP, szKey, iReward)
			return iReward
		}
	}

	if(TrieKeyExists(g_tXPRewards, szKey))
	{
		TrieGetCell(g_tXPRewards, szKey, iReward)
		return iReward
	}

	return 0
}

give_user_xp(const id, iXP, CRXRanks_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
		}
	}
	
	update_vip_status(id)

	new iReturn
	ExecuteForward(g_fwdUserReceiveXP, iReturn, id, iXP, iSource)

	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
	}

	if(g_eSettings[SAVE_INTERVAL] == SAVE_ON_XP_CHANGE)
	{
		save_or_load(id, g_ePlayerData[id][SaveInfo], SL_SAVE_DATA)
	}

	check_level(id, true)
	ExecuteForward(g_fwdUserXPUpdated, iReturn, id, g_ePlayerData[id][XP], iSource)

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

		copy(szKey, charsmax(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", id, szKey, abs(iXP))
		}
		else
		{
			if(bPositive)
			{
				set_hudmessage(XP_NOTIFIER_PARAMS_GET)
			}
			else
			{
				set_hudmessage(XP_NOTIFIER_PARAMS_LOSE)
			}

			ShowSyncHudMsg(id, g_iObject[OBJ_XP_NOTIFIER], "%L", id, szKey, abs(iXP))
		}
	}

	return iXP
}

precache_sound_if_found(const szValue[])
{
	new szSound[MAX_SOUND_LENGTH]
	format(szSound, charsmax(szSound), "sound/%s", szValue)

	if(file_exists(szSound))
	{
		precache_sound(szValue)
	}
	else
	{
		log_amx("ERROR: sound file ^"%s^" not found", szValue)
	}
}

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][HudInfoEnabled] = true
	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")
		SQL_FreeHandle(g_iSqlTuple)
	}
}

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

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

bool:should_send_kill_message(const iXP)
{
	return (g_eSettings[NOTIFY_ON_KILL] && iXP != 0)
}

send_chat_message(const id, const bool:bLog, const szInput[], any:...)
{
	new szMessage[192]
	vformat(szMessage, charsmax(szMessage), szInput, 4)

	if(g_bIsCstrike)
	{
		if(bLog)
		{
			CC_LogMessage(id, _, szMessage)
		}
		else
		{
			CC_SendMessage(id, szMessage)
		}
	}
	else
	{
		format(szMessage, charsmax(szMessage), "%s %s", CC_PREFIX, szMessage)
		client_print(id, print_chat, szMessage)

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

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

	new szMessage[CRXRANKS_MAX_HUDINFO_LENGTH], szPlaceHolder[MAX_NAME_LENGTH], bool:bIsOnFinal

	bIsOnFinal = g_ePlayerData[id][IsOnFinalLevel]
	copy(szMessage, charsmax(szMessage), g_eSettings[bIsOnFinal ? HUDINFO_FORMAT_FINAL : HUDINFO_FORMAT])

	if(has_argument(szMessage, ARG_CURRENT_XP))
	{
		num_to_str(g_ePlayerData[id][XP], szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_CURRENT_XP, szPlaceHolder)
	}

	if(has_argument(szMessage, ARG_NEXT_XP))
	{
		num_to_str(g_ePlayerData[id][NextXP], szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_NEXT_XP, szPlaceHolder)
	}

	if(has_argument(szMessage, ARG_XP_NEEDED))
	{
		num_to_str(g_ePlayerData[id][NextXP] - g_ePlayerData[id][XP], szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_XP_NEEDED, szPlaceHolder)
	}

	if(has_argument(szMessage, ARG_LEVEL))
	{
		num_to_str(g_ePlayerData[id][Level], szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_LEVEL, szPlaceHolder)
	}

	if(has_argument(szMessage, ARG_NEXT_LEVEL))
	{
		num_to_str(g_ePlayerData[id][bIsOnFinal ? Level : Level + 1], szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_NEXT_LEVEL, szPlaceHolder)
	}

	replace_string(szMessage, charsmax(szMessage), ARG_MAX_LEVELS, g_szMaxLevels)

	if(has_argument(szMessage, ARG_NAME))
	{
		get_user_name(id, szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_NAME, szPlaceHolder)
	
	}
	
	if(has_argument(szMessage, ARG_GROUPS))
	{
		agroups_get_user_group(id, szPlaceHolder, charsmax(szPlaceHolder))
		replace_string(szMessage, charsmax(szMessage), ARG_GROUPS, szPlaceHolder)
	}

	replace_string(szMessage, charsmax(szMessage), ARG_RANK, g_ePlayerData[id][Rank])
	replace_string(szMessage, charsmax(szMessage), ARG_NEXT_RANK, g_ePlayerData[id][NextRank])
	replace_string(szMessage, charsmax(szMessage), ARG_LINE_BREAK, "^n")
	copy(g_ePlayerData[id][HUDInfo], charsmax(g_ePlayerData[][HUDInfo]), szMessage)
}

check_level(const id, const bool:bNotify)
{
	new iLevel, i

	for(i = 1; i < g_iMaxLevels + 1; i++)
	{
		if(g_ePlayerData[id][XP] >= ArrayGetCell(g_aLevels, i))
		{
			iLevel++
		}
	}

	if(iLevel != g_ePlayerData[id][Level])
	{
		new bool:bLevelUp, iReturn
		bLevelUp = iLevel > g_ePlayerData[id][Level]
		g_ePlayerData[id][Level] = iLevel
		ArrayGetString(g_aRankNames, iLevel, g_ePlayerData[id][Rank], charsmax(g_ePlayerData[][Rank]))

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

			if(g_eSettings[FINAL_LEVEL_FLAGS])
			{
				set_user_flags(id, g_eSettings[FINAL_LEVEL_FLAGS_BIT])
				remove_user_flags(id, g_iFlagZ)
			}
		}

		ExecuteForward(g_fwdUserLevelUpdated, iReturn, id, iLevel, bLevelUp)

		if(bNotify && g_eSettings[LEVELUP_MESSAGE_TYPE])
		{
			new szName[MAX_NAME_LENGTH]
			get_user_name(id, szName, charsmax(szName))

			if(g_eSettings[LEVELUP_MESSAGE_TYPE] == 2)
			{
				new iPlayers[MAX_PLAYERS], iPlayer, iPnum
				get_players(iPlayers, iPnum)

				for(i = 0; i < iPnum; i++)
				{
					iPlayer = iPlayers[i]
					send_chat_message(iPlayer, false, "%L", iPlayer, bLevelUp ? "CRXRANKS_LEVEL_REACHED" : "CRXRANKS_LEVEL_LOST", szName, g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
				}
			}
			else
			{
				send_chat_message(id, false, "%L", id, bLevelUp ? "CRXRANKS_LEVEL_REACHED" : "CRXRANKS_LEVEL_LOST", szName, g_ePlayerData[id][Level], g_ePlayerData[id][Rank])
			}

			if(bLevelUp && g_eSettings[LEVELUP_SOUND][0])
			{
				emit_sound(id, CHAN_AUTO, g_eSettings[LEVELUP_SOUND], 1.0, ATTN_NORM, 0, PITCH_NORM)
			}
			else if(!bLevelUp && g_eSettings[LEVELDN_SOUND][0])
			{
				emit_sound(id, CHAN_AUTO, g_eSettings[LEVELDN_SOUND], 1.0, ATTN_NORM, 0, PITCH_NORM)
			}

			if(g_eSettings[bLevelUp ? LEVELUP_SCREEN_FADE_ENABLED : LEVELDN_SCREEN_FADE_ENABLED])
			{
				message_begin(MSG_ONE, g_iScreenFade, {0, 0, 0}, id)
				write_short(1<<10)
				write_short(1<<10)
				write_short(0)

				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_has_user_hudinfo",        "_crxranks_has_user_hudinfo")
	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")
	register_native("crxranks_xp_reward_is_set",        "_crxranks_xp_reward_is_set")
}

public _crxranks_get_chat_prefix(iPlugin, iParams)
{
	set_string(1, CC_PREFIX, get_param(2))
}

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

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

public _crxranks_get_max_levels(iPlugin, iParams)
{
	return g_iMaxLevels
}

public _crxranks_get_rank_by_level(iPlugin, iParams)
{
	new iLevel = get_param(1)

	if(iLevel < 1 || iLevel > g_iMaxLevels)
	{
		return 0
	}

	new szRank[CRXRANKS_MAX_RANK_LENGTH]
	ArrayGetString(g_aRankNames, iLevel, szRank, charsmax(szRank))
	set_string(2, szRank, get_param(3))
	return 1
}

public _crxranks_get_save_type(iPlugin, iParams)
{
	return g_eSettings[SAVE_TYPE]
}

public bool:_crxranks_get_setting(iPlugin, iParams)
{
	new szKey[MAX_NAME_LENGTH], szValue[CRXRANKS_MAX_HUDINFO_LENGTH], bool:bReturn
	get_string(1, szKey, charsmax(szKey))

	bReturn = TrieGetString(g_tSettings, szKey, szValue, charsmax(szValue))
	set_string(2, szValue, get_param(3))
	return bReturn
}

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

public _crxranks_get_user_level(iPlugin, iParams)
{
	return g_ePlayerData[get_param(1)][Level]
}

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

public _crxranks_get_user_next_xp(iPlugin, iParams)
{
	return g_ePlayerData[get_param(1)][NextXP]
}

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

public _crxranks_get_user_xp(iPlugin, iParams)
{
	return g_ePlayerData[get_param(1)][XP]
}

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

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

public _crxranks_get_xp_for_level(iPlugin, iParams)
{
	new iLevel = get_param(1)

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

	return ArrayGetCell(g_aLevels, iLevel)
}

public _crxranks_get_xp_reward(iPlugin, iParams)
{
	new szReward[CRXRANKS_MAX_XP_REWARD_LENGTH]
	get_string(2, szReward, charsmax(szReward))
	return get_xp_reward(get_param(1), szReward)
}

public _crxranks_give_user_xp(iPlugin, iParams)
{
	new szReward[CRXRANKS_MAX_XP_REWARD_LENGTH], iReward, id = get_param(1)
	get_string(3, szReward, charsmax(szReward))

	if(szReward[0])
	{
		iReward = get_xp_reward(id, szReward)

		if(iReward)
		{
			give_user_xp(id, iReward, CRXRanks_XPSources:get_param(4))
		}

		return iReward
	}

	iReward = get_param(2)
	give_user_xp(id, iReward, CRXRanks_XPSources:get_param(4))
	return iReward
}

public bool:_crxranks_has_user_hudinfo(iPlugin, iParams)
{
	return g_ePlayerData[get_param(1)][HudInfoEnabled]
}

public bool:_crxranks_is_hi_using_dhud(iPlugin, iParams)
{
	return g_eSettings[HUDINFO_USE_DHUD]
}

public bool:_crxranks_is_hud_enabled(iPlugin, iParams)
{
	return g_eSettings[HUDINFO_ENABLED]
}

public bool:_crxranks_is_sfdn_enabled(iPlugin, iParams)
{
	return g_eSettings[LEVELDN_SCREEN_FADE_ENABLED]
}

public bool:_crxranks_is_sfup_enabled(iPlugin, iParams)
{
	return g_eSettings[LEVELUP_SCREEN_FADE_ENABLED]
}

public bool:_crxranks_is_user_on_final(iPlugin, iParams)
{
	return g_ePlayerData[get_param(1)][IsOnFinalLevel]
}

public bool:_crxranks_is_user_vip(iPlugin, iParams)
{
	return g_ePlayerData[get_param(1)][IsVIP]
}

public bool:_crxranks_is_using_mysql(iPlugin, iParams)
{
	return g_eSettings[USE_MYSQL]
}

public bool:_crxranks_is_xpn_enabled(iPlugin, iParams)
{
	return g_eSettings[XP_NOTIFIER_ENABLED]
}

public bool:_crxranks_is_xpn_using_dhud(iPlugin, iParams)
{
	return g_eSettings[XP_NOTIFIER_USE_DHUD]
}


public bool:_crxranks_set_user_xp(iPlugin, iParams)
{
	new iReturn, id = get_param(1), CRXRanks_XPSources:iSource = CRXRanks_XPSources:get_param(3)
	g_ePlayerData[id][XP] = clamp(get_param(2), 0)

	if(g_eSettings[SAVE_INTERVAL] == SAVE_ON_XP_CHANGE)
	{
		save_or_load(id, g_ePlayerData[id][SaveInfo], SL_SAVE_DATA)
	}

	check_level(id, true)
	ExecuteForward(g_fwdUserXPUpdated, iReturn, id, g_ePlayerData[id][XP], iSource)
}

public bool:_crxranks_using_comb_events(iPlugin, iParams)
{
	return g_eSettings[USE_COMBINED_EVENTS]
}

public bool:_crxranks_xp_reward_is_set(iPlugin, iParams)
{
	new szReward[CRXRANKS_MAX_XP_REWARD_LENGTH]
	get_string(1, szReward, charsmax(szReward))
	return xp_reward_is_set(szReward)
}

Аватар
SCORPION123
Извън линия
Потребител
Потребител
Мнения: 44
Регистриран на: 20 Фев 2019, 12:03
Се отблагодари: 12 пъти

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

Мнение от SCORPION123 » 02 Окт 2020, 15:19

Интересувам се как мога да обърна префиксите когато свържа префикса на ранк системата към чата да излиза [Първо префикса зададен за играча][Ранк префикс]

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

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

Мнение от OciXCrom » 02 Окт 2020, 16:27

От [Format Definitions] в .ini файла.

Аватар
SCORPION123
Извън линия
Потребител
Потребител
Мнения: 44
Регистриран на: 20 Фев 2019, 12:03
Се отблагодари: 12 пъти

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

Мнение от SCORPION123 » 02 Окт 2020, 19:20

OciXCrom написа: 02 Окт 2020, 16:27 От [Format Definitions] в .ini файла.
Малко по подробно за процедурата ако обичаш, благодаря.

Аватар
gadinkata
Извън линия
Потребител
Потребител
Мнения: 259
Регистриран на: 21 Мар 2018, 12:33
Местоположение: Враца
Се отблагодари: 25 пъти
Получена благодарност: 7 пъти
Обратна връзка:

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

Мнение от gadinkata » 02 Окт 2020, 20:45

Тъй като този плъгин главно се отнася за XP-то, нивата и ранковете, а не за чата, нужно е да изтеглите плъгина Chat Manager за да има ранкове в чата.
Добавил съм поддържка в Chat Manager за този плъгин, тъй че по доста лесен начин можете да активирате ранковете.
Въпросната активация на ранковете става като в раздела [Format Definitions] добавите ключовата дума $rank$, която ще показва ранка в чата където искате. Можете да я направите само за обикновени играчи, заедно с админ префикса и тн.
Ако не знаете как и къде да я добавите, следвайте стъпките:

Отваряте конфигурационния файл - configs/ChatManager.ini.
Търсите раздела [Format Definitions] и замествате 4-те настройки в него с тези:
format_admin = $dead_prefix$ &x04[$rank$] $admin_prefix$ &x03$custom_name$ &x01: $chat_color$$message$ format_admin_team = $dead_prefix$ ($team$) &x04[$rank$] $admin_prefix$ &x03$custom_name$ &x01: $chat_color$$message$ format_player = $dead_prefix$ &x04[$rank$] &x03$custom_name$ &x01: $chat_color$$message$ format_player_team = $dead_prefix$ ($team$) &x04[$rank$] &x03$custom_name$ &x01: $chat_color$$message$

==>
format_admin = $dead_prefix$ $admin_prefix$ &x04[$rank$] &x03$custom_name$ &x01: $chat_color$$message$ format_admin_team = $dead_prefix$ ($team$) &x04 $admin_prefix$ &x04[$rank$] &x03$custom_name$ &x01: $chat_color$$message$ format_player = $dead_prefix$ &x04 &x03$custom_name$ &x04[$rank$] &x01: $chat_color$$message$ format_player_team = $dead_prefix$ ($team$) &x04[$rank$] &x03$custom_name$ &x01: $chat_color$$message$

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

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

Мнение от OciXCrom » 03 Окт 2020, 00:20

SCORPION123 написа: 02 Окт 2020, 19:20
OciXCrom написа: 02 Окт 2020, 16:27 От [Format Definitions] в .ini файла.
Малко по подробно за процедурата ако обичаш, благодаря.
Просто трябва да замениш местата на $rank$ и $admin_prefix$.

Аватар
tom1k
Извън линия
Потребител
Потребител
Мнения: 202
Регистриран на: 29 Сеп 2020, 23:50
Местоположение: Добрич
Се отблагодари: 16 пъти
Получена благодарност: 8 пъти

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

Мнение от tom1k » 09 Окт 2020, 00:24

Каква ще е стойността за HUDINFO_POSITION = да бъде най-горе посредата на екрана?
iG-Blockmaker # HNS 100aa
45.144.155.175:27018


Публикувай отговор
  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Одобрени плъгини”

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 12 госта