#pragma semicolon 1
#include <amxmodx>
#include <reapi>
#include <nvault>
enum _:szRank {
Rank_Name,
Rank_MaxXp,
Rank_TxtSprFileName
}
/* {"RankName", Maximum XP to level up, "txt_spr_name"} */
new const szRankNames[][][] = {
{"Unranked", 20, ""},
{"Silver I", 20, "silver1"},
{"Silver II", 24, "silver2"},
{"Silver III", 28, "silver3"},
{"Silver IV", 32, "silver4"},
{"Silver Elite", 36, "silverelite"},
{"Silver Elite Master", 40, "silverelitemaster"},
{"Gold Nova I", 45, "goldnova1"},
{"Gold Nova II", 50, "goldnova2"},
{"Gold Nova III", 55, "goldnova3"},
{"Gold Nova Master", 60, "goldnovamaster"},
{"Master Guardian I", 66, "masterguardian1"},
{"Master Guardian II", 72, "masterguardian2"},
{"Master Guardian Elite", 78, "masterguardianelite"},
{"Distinguished Master Guardian", 86, "distinguishedmasterguardian"},
{"Legendary Eagle", 95, "legendaryeagle"},
{"Legendary Eagle Master", 105, "legendaryeaglemaster"},
{"Supreme Master First Class", 110, "suprememasterfirstclass"},
{"The Global Elite", 120, "theglobalelite"}
};
new bool:g_PlayerRankedUp[MAX_CLIENTS + 1],
g_rank[MAX_CLIENTS + 1],
g_xp[MAX_CLIENTS + 1],
pCvars[6],
pMsgIds[4],
pForward[2],
hud_sync;
public plugin_init() {
register_plugin("Advanced Rank System", "0.0.2", "PurposeLess");
register_event("CurWeapon", "@Event_CurWeapon", "be", "1=1");
RegisterHookChain(RG_CBasePlayer_Killed, "@CBasePlayer_Killed", .post = true);
if(get_member_game(m_bMapHasBombZone)) {
RegisterHookChain(RG_CGrenade_DefuseBombEnd, "@CGrenade_DefuseBombEnd", .post = true);
RegisterHookChain(RG_PlantBomb, "@PlantBomb", .post = true);
}
bind_pcvar_num(create_cvar("ars_dead_xp", "-2"), pCvars[0]);
bind_pcvar_num(create_cvar("ars_kill_xp", "3"), pCvars[1]);
bind_pcvar_num(create_cvar("ars_kill_hp_xp", "2"), pCvars[2]);
bind_pcvar_num(create_cvar("ars_defuse_xp", "3"), pCvars[3]);
bind_pcvar_num(create_cvar("ars_plant_xp", "3"), pCvars[4]);
bind_pcvar_num(create_cvar("ars_spr_appear_time", "5"), pCvars[5]);
pMsgIds[0] = get_user_msgid("WeaponList");
pMsgIds[1] = get_user_msgid("SetFOV");
pMsgIds[2] = get_user_msgid("CurWeapon");
pMsgIds[3] = get_user_msgid("HideWeapon");
pForward[0] = CreateMultiForward("ars_rank_up", ET_IGNORE, FP_CELL);
pForward[1] = CreateMultiForward("ars_rank_down", ET_IGNORE, FP_CELL);
hud_sync = CreateHudSyncObj();
}
public plugin_precache() {
for(new i = 1; i < sizeof(szRankNames); i++) {
precache_generic(fmt("sprites/ars/%s.txt", szRankNames[i][Rank_TxtSprFileName][0]));
precache_generic(fmt("sprites/ars/%s.spr", szRankNames[i][Rank_TxtSprFileName][0]));
}
}
public plugin_natives() {
register_native("ars_get_user_xp", "@ars_get_user_xp");
register_native("ars_get_user_rank", "@ars_get_user_rank");
register_native("ars_get_user_rankname", "@ars_get_user_rankname");
}
@ars_get_user_xp() {
new pPlayer = get_param(1);
return g_xp[pPlayer];
}
@ars_get_user_rank() {
new pPlayer = get_param(1);
return g_rank[pPlayer];
}
@ars_get_user_rankname() {
new pPlayer = get_param(1);
set_array(2, szRankNames[g_rank[pPlayer]][Rank_Name], get_param(3));
}
public client_putinserver(pPlayer) {
if(is_user_bot(pPlayer)) {
return;
}
set_task(1.0, "@ShowHudmessage", pPlayer, .flags = "b");
}
@ShowHudmessage(const pPlayer) {
set_hudmessage(210, 105, 30, 0.01, 0.15, 0, _, 1.0, 0.1, 0.1);
ShowSyncHudMsg(pPlayer, hud_sync, "Rank: %s^nRank Xp: %i/%i", szRankNames[g_rank[pPlayer]][Rank_Name], g_xp[pPlayer], szRankNames[g_rank[pPlayer]][Rank_MaxXp]);
}
@Event_CurWeapon(const pPlayer) {
if(!g_PlayerRankedUp[pPlayer] || get_member(pPlayer, m_iFOV) != 90) {
return;
}
Show_Rank_Event(pPlayer);
}
@CBasePlayer_Killed(const pVictim, pAttacker, iGib) {
if(pVictim == pAttacker || !is_user_connected(pAttacker)) {
return;
}
g_xp[pVictim] += pCvars[0];
g_xp[pAttacker] += pCvars[1];
if(get_member(pVictim, m_bHeadshotKilled)) {
g_xp[pAttacker] += pCvars[2];
}
RankCheck(pAttacker);
RankCheck(pVictim);
}
@CGrenade_DefuseBombEnd(const pBomb, const pPlayer, bool:bDefused) {
if(bDefused && pCvars[3]) {
g_xp[pPlayer] += pCvars[3];
RankCheck(pPlayer);
}
}
@PlantBomb(const pPlayer, Float:vecStart[3], Float:vecVelocity[3]) {
if(pCvars[4]) {
g_xp[pPlayer] += pCvars[4];
RankCheck(pPlayer);
}
}
const TASKID_ARS = 1337;
RankCheck(const pPlayer) {
if(g_xp[pPlayer] >= szRankNames[g_rank[pPlayer]][Rank_MaxXp][0]) {
if(g_rank[pPlayer] == sizeof(szRankNames) - 1) {
g_xp[pPlayer] = szRankNames[g_rank[pPlayer]][Rank_MaxXp][0];
return;
}
g_xp[pPlayer] -= szRankNames[g_rank[pPlayer]][Rank_MaxXp][0];
g_rank[pPlayer]++;
g_PlayerRankedUp[pPlayer] = true;
Show_Rank_Event(pPlayer);
remove_task(pPlayer + TASKID_ARS);
set_task(float(pCvars[5]), "@Clear_Rank_Event", pPlayer + TASKID_ARS);
ExecuteForward(pForward[0], _, pPlayer);
}
else if(g_xp[pPlayer] <= 0) {
if(g_rank[pPlayer] < 2) {
g_xp[pPlayer] = 0;
return;
}
g_rank[pPlayer]--;
g_xp[pPlayer] = szRankNames[g_rank[pPlayer]][Rank_MaxXp][0] - g_xp[pPlayer];
ExecuteForward(pForward[1], _, pPlayer);
}
}
Show_Rank_Event(const pPlayer) {
new ammo, weapon = get_user_weapon(pPlayer, ammo);
switch(weapon) {
case CSW_P228: SetMessage_WeaponList(pPlayer, 9, 52);
case CSW_HEGRENADE: SetMessage_WeaponList(pPlayer, 12, 1);
case CSW_XM1014: SetMessage_WeaponList(pPlayer, 5, 32);
case CSW_C4: SetMessage_WeaponList(pPlayer, 14, 1);
case CSW_MAC10: SetMessage_WeaponList(pPlayer, 6, 100);
case CSW_AUG: SetMessage_WeaponList(pPlayer, 4, 90);
case CSW_SMOKEGRENADE: SetMessage_WeaponList(pPlayer, 13, 1);
case CSW_ELITE: SetMessage_WeaponList(pPlayer, 10, 120);
case CSW_FIVESEVEN: SetMessage_WeaponList(pPlayer, 7, 100);
case CSW_UMP45: SetMessage_WeaponList(pPlayer, 6, 100);
case CSW_GALIL: SetMessage_WeaponList(pPlayer, 4, 90);
case CSW_FAMAS: SetMessage_WeaponList(pPlayer, 4, 90);
case CSW_USP: SetMessage_WeaponList(pPlayer, 6, 100);
case CSW_GLOCK18: SetMessage_WeaponList(pPlayer, 10, 120);
case CSW_MP5NAVY: SetMessage_WeaponList(pPlayer, 10, 120);
case CSW_M249: SetMessage_WeaponList(pPlayer, 3, 200);
case CSW_M3: SetMessage_WeaponList(pPlayer, 5, 32);
case CSW_M4A1: SetMessage_WeaponList(pPlayer, 4, 90);
case CSW_TMP: SetMessage_WeaponList(pPlayer, 10, 120);
case CSW_FLASHBANG: SetMessage_WeaponList(pPlayer, 11, 2);
case CSW_DEAGLE: SetMessage_WeaponList(pPlayer, 8, 35);
case CSW_SG552: SetMessage_WeaponList(pPlayer, 4, 90);
case CSW_AK47: SetMessage_WeaponList(pPlayer, 2, 90);
case CSW_KNIFE: SetMessage_WeaponList(pPlayer, -1, -1);
case CSW_P90: SetMessage_WeaponList(pPlayer, 7, 100);
case CSW_SCOUT: SetMessage_WeaponList(pPlayer, 2, 90);
case CSW_SG550: SetMessage_WeaponList(pPlayer, 4, 90);
case CSW_AWP: SetMessage_WeaponList(pPlayer, 1, 30);
case CSW_G3SG1: SetMessage_WeaponList(pPlayer, 2, 90);
default: return;
}
SetMessage_SetFOV(pPlayer, 89);
SetMessage_CurWeapon(pPlayer, ammo);
SetMessage_SetFOV(pPlayer, 90);
}
@Clear_Rank_Event(TaskId) {
new pPlayer = TaskId - TASKID_ARS;
g_PlayerRankedUp[pPlayer] = false;
SetMessage_HideWeapon(pPlayer);
}
SetMessage_WeaponList(const pPlayer, const pAmmoId, const pAmmoMaxAmount) {
message_begin(MSG_ONE, pMsgIds[0], .player = pPlayer); {
write_string(fmt("ars/%s", szRankNames[g_rank[pPlayer]][Rank_TxtSprFileName]));
write_byte(pAmmoId);
write_byte(pAmmoMaxAmount);
write_byte(-1);
write_byte(-1);
write_byte(0);
write_byte(11);
write_byte(2);
write_byte(0);
}
message_end();
}
SetMessage_SetFOV(const pPlayer, const FOV) {
message_begin(MSG_ONE, pMsgIds[1], .player = pPlayer); {
write_byte(FOV);
}
message_end();
}
SetMessage_CurWeapon(const pPlayer, const ammo) {
message_begin(MSG_ONE, pMsgIds[2], .player = pPlayer); {
write_byte(1);
write_byte(2);
write_byte(ammo);
}
message_end();
}
SetMessage_HideWeapon(const pPlayer) {
message_begin(MSG_ONE, pMsgIds[3], .player = pPlayer);
write_byte(0);
message_end();
}
/* nvault */
new g_vault;
public plugin_cfg() {
g_vault = nvault_open("AdvancedRankSystem");
if(g_vault == INVALID_HANDLE) {
set_fail_state("Unknown nvault for AdvancedRankSystem");
}
}
public plugin_end() {
nvault_close(g_vault);
}
public client_authorized(pPlayer, const authid[]) {
g_xp[pPlayer] = nvault_get(g_vault, fmt("%s_xp", authid));
g_rank[pPlayer] = nvault_get(g_vault, fmt("%s_rank", authid));
}
public client_disconnected(pPlayer) {
new authid[MAX_AUTHID_LENGTH], data[MAX_AUTHID_LENGTH+10];
get_user_authid(pPlayer, authid, charsmax(authid));
num_to_str(g_xp[pPlayer], data, charsmax(data));
nvault_pset(g_vault, fmt("%s_xp", authid), data);
num_to_str(g_rank[pPlayer], data, charsmax(data));
nvault_pset(g_vault, fmt("%s_rank", authid), data);
remove_task(pPlayer);
remove_task(pPlayer + TASKID_ARS);
}