Код
/* AMX Mod X plugin
*
* Name: RPG mod
* Author: Sylwester
* Version: 1.11
* Release Date: -
*
*
* Credits:
* SeLfkiLL (orginal idea - RPG mod for CS:S)
*
*
* Changelog:
* 1.0b3 (26 June 2009):
* - added MySql support (using sqlx module)
* - added bots support (start lvl, data saving, buying upgrades)
* - added settings menu
* - modified login info menu
* - added cvars:
* rpgm_savedb
* rpgm_frequent_save
* rpgm_start_lvl
* rpgm_in_team
* rpgm_def_upgrades
* rpgm_bot_start_lvl
* rpgm_bot_savedata
* rpgm_bot_buy_upgs
* rpgm_bot_def_upgrades
* rpgm_sql_host
* rpgm_sql_user
* rpgm_sql_pass
* rpgm_sql_db
* rpgm_user_control
* - added commands:
* amx_rpg_lvl
* amx_rpg_drop_upgs
* amx_rpg_set_upgs
* amx_rpg_global_reset
* - removed cvar rpgm_start_cr
*
* 1.0b2 (21 June 2009):
* - bugfix (xp reset when using say)
*
* 1.0b1 (9 June 2009):
* - bugfix (index out of bounds in show_levels)
*
* 1.0b (8 June 2009):
* - first release
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <fun>
#include <cstrike>
#include <nvault>
#include <sqlx>
#define VERSION "1.11"
#define MAX_PLAYERS 32
#define UPDATE_INTERVAL 0.1 //do not modify
#define TID_TIMER 3536
#define MAX_LVL 99999
#define MAX_XP_MULTI 99999.0
#define MAX_UPGS 20
#define UPG_REGEN 0
#define UPG_HEALTH 1
#define UPG_RESUP 2
#define UPG_VAMP 3
#define UPG_STEALTH 4
#define UPG_LJ 5
#define UPG_ICESTAB 6
#define UPG_FROST 7
#define UPG_DENIAL 8
#define UPG_IMPULSE 9
#define UPG_MEDIC 10
#define UPG_BHOP 11
#define UPG_ARM_REGEN 12
#define UPG_HE_DMG 13
#define UPG_WPN_DMG 14
#define UPG_APWSCOUT_DMG 15
#define UPG_DMG_REDUCE 16
#define UPG_ANTI_FROSTKNIFE 17
#define UPG_ANTI_ICESTAB 18
#define UPG_BEE_STING 19
#define DENIAL_BLOCK -3
#define DENIAL_NEXT_SPAWN -4
#define DENIAL_START 10
#define DENIAL_STRIP 8
#define DENIAL_GIVE 7
#define CREDITS_PER_LVL 10
#define CXT_KILL 0 //arg1: attacker, arg2: victim
#define CXT_DMG 1 //arg1: attacker, arg2: victim, arg3: dmg_amount
#define XP_START 600
#define XP_INC 5
#define DATA_NOT_LOADED 0
#define DATA_NOT_FOUND 1
#define DATA_LOADED 2
#define DATA_LOADING 3
#define SAVEBY_STEAMID 1
#define SAVEBY_IP 2
#define SAVEBY_NAME 3
#define SAVEBY_LOGIN 4 //special case (g_saveby is never equal 4)
#define SAVEBY_BOT 5 //special case (g_saveby is never equal 5)
#define SAVEDB_NVAULT 1
#define SAVEDB_MYSQL 2
#define REG_NONE 1
#define REG_TRY 2
#define REG_DONE 3
#define DB_NONE 0
#define DB_CONNECTING 1
#define DB_READY 2
#define LOGIN_COOLDOWN 10.0
#define FREQ_S_NONE 0
#define FREQ_S_NEW_ROUND 1
#define FREQ_S_INTERVAL 2
#define MAX_SETTINGS 2
#define SETT_MENU_ON_SPAWN 0
#define SETT_INFO_UNDER_CHAT 1
new g_max_players
new Float:g_t_time
new g_timer_entid
new Float:g_p_login_time[MAX_PLAYERS+1]
new g_p_xp[MAX_PLAYERS+1]
new g_p_temp_xp[MAX_PLAYERS+1] //xp gained since last save
new g_p_credits[MAX_PLAYERS+1]
new g_p_upg[MAX_PLAYERS+1][MAX_UPGS]
new g_p_level[MAX_PLAYERS+1]
new g_p_progress[MAX_PLAYERS+1]
new g_p_menu_page[MAX_PLAYERS+1]
new g_p_team[MAX_PLAYERS+1]
new g_p_settings[MAX_PLAYERS+1][MAX_SETTINGS]
new g_settings_maxval[MAX_SETTINGS] = {1, 1}
new g_settings_default[MAX_SETTINGS+1] = "11"
new bool:g_p_authorized[MAX_PLAYERS+1]
new bool:g_upg_enabled[MAX_UPGS]
new g_enabled_upgs
new g_enabled_list[MAX_UPGS]
new g_upg_name[MAX_UPGS][32] = {"Регенерация", "Жизни", "Снабжение", "Вампир", "Невидимка",
"Прыжок", "Нож", "Пистолет", "Дэниал", "Импульс", "Медик", "Распрыжка", "Реген брони",
"Граната+", "Заточка оружия", "Снайпер", "Силовой щит", "Антипистолет", "Антинож", "Укус пчелы"}
new g_upg_sp[MAX_UPGS] = {25,25,10,25,30,30,150,10,500,30,20,500,25,50,25,200,50,15,200,30}
new g_upg_ip[MAX_UPGS] = {25,25,5,25,30,25,150,5,5,30,5,900,25,50, 25, 25, 25, 5, 200, 30}
new g_upg_maxlvl[MAX_UPGS] = {25, 40, 10, 30, 5, 5, 3, 15, 1, 10, 25, 1, 20, 6, 40, 20, 30, 15, 3, 5}
new g_p_sm_upg[MAX_PLAYERS+1][MAX_UPGS] //list of upgs displayed in sell menu
new g_p_sm_upg_cnt[MAX_PLAYERS+1] //amount of upgs on the list
new g_max_bpammo[33] = {0,52,0,90,1,32,1,100,90,1,120,100,100,90,90,90,100,120,30,120,200,32,90,120,90,
2,35,90,90,0,100,0,0}
new g_gi_names[32][32] = {"", "weapon_p228", "", "weapon_scout", "weapon_hegrenade",
"weapon_xm1014", "weapon_c4", "weapon_mac10", "weapon_aug", "weapon_smokegrenade", "weapon_elite",
"weapon_fiveseven", "weapon_ump45", "weapon_sg550", "weapon_galil", "weapon_famas", "weapon_usp", "weapon_glock18",
"weapon_awp", "weapon_mp5navy", "weapon_m249", "weapon_m3", "weapon_m4a1", "weapon_tmp",
"weapon_g3sg1", "weapon_flashbang", "weapon_deagle", "weapon_sg552", "weapon_ak47",
"weapon_knife", "weapon_p90", ""}
new Float:g_weap_speed[32] = {0.0, 250.0, 0.0, 260.0, 250.0, 240.0, 250.0, 250.0, 240.0,
250.0, 250.0, 250.0, 250.0, 210.0, 240.0, 240.0, 250.0, 250.0, 210.0, 250.0, 220.0, 230.0,
230.0, 250.0, 210.0, 250.0, 250.0, 235.0, 221.0, 250.0, 245.0, 0.0}
new pc_xp_mult
new pc_admin_xp_mult
new pc_vip_xp_mult
new pc_upgs
new Float:g_mradius
new Float:g_sq_mradius
new Float:g_p_angle[MAX_PLAYERS+1][3]
new g_c_regen[MAX_PLAYERS+1]
new g_c_arm_regen[MAX_PLAYERS+1]
new g_p_maxhealth[MAX_PLAYERS+1]
new g_c_resup[MAX_PLAYERS+1]
new Float:g_p_next_lj[MAX_PLAYERS+1]
new bool:g_p_jump[MAX_PLAYERS+1]
new g_c_frost[MAX_PLAYERS+1]
new g_c_ice[MAX_PLAYERS+1]
new g_c_denial[MAX_PLAYERS+1]
new g_c_impulse[MAX_PLAYERS+1]
new g_c_medic[MAX_PLAYERS+1]
new bool:g_block_denial //if true, denial will not work on next round
new g_p_buttons[MAX_PLAYERS+1]
new bool:g_p_alive[MAX_PLAYERS+1]
new g_p_weap_num[MAX_PLAYERS+1]
new g_p_weap[MAX_PLAYERS+1][32]
new g_p_has_c4[MAX_PLAYERS+1]
new CsArmorType:g_p_atype[MAX_PLAYERS+1]
new g_p_armor[MAX_PLAYERS+1]
new Float:g_xp_multipler
new Float:g_admin_xp_multipler
new Float:g_vip_xp_multipler
new g_msgStatusText
new pc_savedata
new pc_saveby
new pc_savedb
new pc_frequent_save
new pc_sql_host
new pc_sql_user
new pc_sql_pass
new pc_sql_db
new pc_start_lvl
new pc_bot_start_lvl
new pc_bot_savedata
new pc_bot_buy_upgrades
new pc_def_upgs
new pc_bot_def_upgs
new pc_user_control
new pc_in_team
new bool:g_freezetime
new g_p_authid[MAX_PLAYERS+1][32]
new g_p_ip[MAX_PLAYERS+1][32]
new g_p_name[MAX_PLAYERS+1][32]
new g_p_data_loaded[MAX_PLAYERS+1]
new g_p_defkit[MAX_PLAYERS+1]
new g_saveby
new g_saveby_name[6][16] = {"", "rpgm_sid", "rpgm_ip", "rpgm_name", "rpgm_reg", "rpgm_bot"}
new g_savedb
new g_p_username[MAX_PLAYERS+1][32]
new g_p_password[MAX_PLAYERS+1][32]
new g_p_login_status[MAX_PLAYERS+1]
new bool:g_p_pw_hidden[MAX_PLAYERS+1]
new Handle:g_sql_tuple
new Handle:g_sql_connection
new g_db_status
new g_sql_tables
new g_frequent_save
new g_bot_savedata
new g_bot_def_upgs[MAX_UPGS]
new g_bot_def_cost
new g_bot_def_lvl_req
new g_def_upgs[MAX_UPGS]
new g_def_cost
new g_def_lvl_req
new g_user_control
new g_in_team
public plugin_init(){
register_plugin("RPG mod", VERSION, "Sylwester")
register_cvar("rpgm_ver", VERSION, FCVAR_SERVER)
g_msgStatusText = get_user_msgid("StatusText")
g_max_players = get_maxplayers()
register_clcmd("say", "handle_say")
register_clcmd("say_team", "handle_say")
register_clcmd("rpgmenu", "menu_main")
register_clcmd("say lvl", "show_levels")
register_clcmd("amx_login", "rpg_login", -1, "<username> <password> ")
register_clcmd("amx_rpg_lvl", "change_lvl_cmd", ADMIN_CVAR, "<@all|@t|@ct|#userid|name> <+|=|-> <amount> - changes target level ")
register_clcmd("amx_rpg_drop_upgs", "drop_upg_cmd", ADMIN_CVAR, "<@all|@t|@ct|#userid|name> - forces target(s) to sell all upgrades ")
register_clcmd("amx_rpg_set_upgs", "set_upg_cmd", ADMIN_CVAR, "<@all|@t|@ct|#userid|name> <upgrades string> - set target(s) upgrades ")
register_srvcmd("amx_rpg_global_reset", "global_data_reset", ADMIN_CVAR, "<RENAME|DELETE> - rename or delete all current data files/tables ")
pc_xp_mult = register_cvar("rpgm_xp_mult", "1.0", 0, 1.0)
pc_admin_xp_mult = register_cvar("rpgm_admin_xp_mult", "1.0", 0, 1.0)
pc_vip_xp_mult = register_cvar("rpgm_vip_xp_mult", "1.0", 0, 1.0)
pc_upgs = register_cvar("rpgm_upgs", "111111111111")
pc_savedata = register_cvar("rpgm_savedata", "1") //1 - yes //0 - no
pc_saveby = register_cvar("rpgm_saveby", "1") //1 - steamid //2 - ip //3 - name
pc_savedb = register_cvar("rpgm_savedb", "1") //1 - nvault //2 - sql
pc_frequent_save = register_cvar("rpgm_frequent_save", "1")
//0-save only on disconnect //1-save all on new round
//2-every 10secs save player with highest xp gained since last save
pc_start_lvl = register_cvar("rpgm_start_lvl", "0")
pc_bot_start_lvl = register_cvar("rpgm_bot_start_lvl", "0")
pc_bot_savedata = register_cvar("rpgm_bot_savedata", "0")
pc_bot_buy_upgrades = register_cvar("rpgm_bot_buy_upgrades", "0")
pc_def_upgs = register_cvar("rpgm_def_upgrades", "000000000000")
pc_bot_def_upgs = register_cvar("rpgm_bot_def_upgrades", "0000000000000")
pc_user_control = register_cvar("rpgm_user_control", "1")
pc_sql_host = register_cvar("rpgm_sql_host", "")
pc_sql_user = register_cvar("rpgm_sql_user", "")
pc_sql_pass = register_cvar("rpgm_sql_pass", "")
pc_sql_db = register_cvar("rpgm_sql_db", "")
pc_in_team = register_cvar("rpgm_in_team", "0") //0-both team //1-only terro //2-only ct
register_event("Damage", "damage_event", "b", "2!0")
register_event("DeathMsg", "player_death", "a")
register_event("CurWeapon", "event_CurWeapon", "be", "1=1")
register_event("HLTV", "event_new_round", "a", "1=0", "2=0")
register_logevent("logevent_round_start", 2, "1=Round_Start")
register_event("TextMsg", "block_denial", "a", "2&#Game_C") //game commencing
register_event("TextMsg", "block_denial", "a", "2&#Game_will_restart_in") //round restart
register_message(get_user_msgid("Health"), "fix_0hp")
register_menucmd(register_menuid("\yRPG mod \d[#]"), 1023, "hnd_menu_main")
register_menucmd(register_menuid("\yRPG mod \d[#.1]"), 1023, "hnd_menu_buy_upg")
register_menucmd(register_menuid("\yRPG mod \d[#.2]"), 1023, "hnd_menu_sell_upg")
register_menucmd(register_menuid("\yRPG mod \d[#.4]"), 1023, "hnd_menu_help")
register_menucmd(register_menuid("\yRPG mod \d[#.5]"), 1023, "hnd_menu_settings")
register_menucmd(register_menuid("\yRPG mod \d[#.6]"), 1023, "hnd_menu_data")
register_menucmd(register_menuid("\yRPG mod \d[#.3]"), 1023, "hnd_menu_show_levels")
RegisterHam(Ham_Spawn, "player", "player_spawn", 1)
RegisterHam(Ham_TakeDamage, "player", "Player_TakeDamage");
register_forward(FM_PlayerPreThink, "player_PreThink")
register_forward(FM_PlayerPostThink, "player_PostThink")
register_forward(FM_CmdStart,"fwd_CmdStart")
//exec_cfg_file() //rpg mod cfg file unfinished
create_timer()
g_db_status = DB_NONE
set_task(0.1, "prepare_database")
}
public global_data_reset(id, level, cid){
new arg[32], path[128], file[128], cache[128], temp[128], file2[128]
if (!cmd_access(id, level, cid, 2))
return PLUGIN_HANDLED
read_args(arg, 31)
if(g_db_status == DB_NONE){
log_amx("SERVER: [ amx_rpg_global_reset %s ] - database not connected", arg)
return PLUGIN_HANDLED
}
get_datadir(path, 127)
format(path, 127, "%s/vault/", path)
if(contain(arg, "DELETE")==0){
g_db_status = DB_NONE
if(g_savedb==SAVEDB_NVAULT){
for(new i=1; i<6; i++){
format(file, 127, "%s%s.vault", path, g_saveby_name[i])
if(file_exists(file) && !delete_file(file)){
log_amx("SERVER: [ amx_rpg_global_reset %s ] - failure while trying to delete file %s", arg, file)
return PLUGIN_HANDLED
}
}
}else if(g_savedb==SAVEDB_MYSQL){
for(new i=1; i<6; i++){
format(cache, 127, "drop table if exists %s;", g_saveby_name[i])
SQL_ThreadQuery(g_sql_tuple, "handle_change_table_query", cache)
}
}
}else if(contain(arg, "RENAME")==0){
g_db_status = DB_NONE
get_time("%y%m%d%H%M%S", temp, 127)
if(g_savedb==SAVEDB_NVAULT){
for(new i=1; i<6; i++){
format(file, 127, "%s%s.vault", path, g_saveby_name[i])
format(file2, 127, "%s%s_%s.vault", path, temp, g_saveby_name[i])
if(file_exists(file) && !rename_file(file, file2, 1)){
log_amx("SERVER: [ amx_rpg_global_reset %s ] - failure while trying to rename file %s", arg, file)
return PLUGIN_HANDLED
}
}
}else if(g_savedb==SAVEDB_MYSQL){
for(new i=1; i<6; i++){
format(cache, 127, "RENAME TABLE %s TO %s_%s;", g_saveby_name[i], temp, g_saveby_name[i])
SQL_ThreadQuery(g_sql_tuple, "handle_change_table_query", cache)
}
}
}else{
log_amx("SERVER: [ amx_rpg_global_reset %s ], invalid argument - must be DELETE or RENAME", arg)
return PLUGIN_HANDLED
}
log_amx("SERVER: [ amx_rpg_global_reset %s ] - success", arg)
prepare_database()
return PLUGIN_HANDLED
}
public handle_change_table_query(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
if(FailState){
log_amx("SQL Error: %s (%d)", Error, Errcode)
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public prepare_database(){
g_db_status = DB_NONE
g_frequent_save = get_pcvar_num(pc_frequent_save)
g_bot_savedata = get_pcvar_num(pc_bot_savedata)
if(get_pcvar_num(pc_savedata) == 0)
return
g_saveby = get_pcvar_num(pc_saveby)
if(g_saveby < 1 || g_saveby > 3) //1 - steamid //2 - ip //3 - name
g_saveby = 1
g_savedb = get_pcvar_num(pc_savedb)
if(g_savedb < 1 || g_savedb > 2)
g_savedb = 1
switch(g_savedb){
case SAVEDB_MYSQL: sql_init()
case SAVEDB_NVAULT: {
g_db_status = DB_READY
p_vars_reset_all()
data_load_all()
}
}
}
public incorrect_login_data(id){
client_print(id, print_chat, "[RPG mod]Ошибка: имя пользователя и пароль должны быть 3-10 символов")
client_print(id, print_chat, "[RPG mod]Ошибка: имя пользователя и пароль должны содержать только буквы, цифры, - и _")
client_print(id, print_console, "[RPG mod]Ошибка: имя пользователя и пароль должны быть 3-10 символов")
client_print(id, print_console, "[RPG mod]Error: имя пользователя и пароль должны содержать только буквы, цифры, - и _")
return PLUGIN_HANDLED
}
public rpg_login(id, level, cid){
static cache[128], len, Float:time
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED
if(g_p_login_status[id] == REG_DONE){
client_print(id, print_chat, "[RPG mod]Ошибка: Вы уже залогинены")
client_print(id, print_console, "[RPG mod]Ошибка: Вы уже залогинены")
return PLUGIN_HANDLED
}
time = get_gametime()
if(time - g_p_login_time[id] < LOGIN_COOLDOWN && g_p_login_time[id] != 0.0){
client_print(id, print_chat, "[RPG mod]Ошибка: вы можете использовать amx_login только один раз в %.0f секинд", LOGIN_COOLDOWN)
client_print(id, print_console, "[RPG mod]Ошибка: вы можете использовать amx_login только один раз в %.0f секунд", LOGIN_COOLDOWN)
return PLUGIN_HANDLED
}
g_p_login_time[id] = time
read_args(cache, 127)
strbreak(cache, g_p_username[id], 31, cache, 127)
remove_quotes(g_p_username[id])
len = strlen(g_p_username[id])
if(len<3 || len>10){
incorrect_login_data(id)
}
for(new i=0; i<len; i++){
if((g_p_username[id][i] < 'a' || g_p_username[id][i] > 'z') &&
(g_p_username[id][i] < 'A' || g_p_username[id][i] > 'Z') &&
(g_p_username[id][i] < '0' || g_p_username[id][i] > '9') &&
g_p_username[id][i] != '-' && g_p_username[id][i] != '_'){
incorrect_login_data(id)
}
}
strbreak(cache, g_p_password[id], 31, cache, 127)
remove_quotes(g_p_password[id])
len = strlen(g_p_password[id])
if(len<3 || len>10){
incorrect_login_data(id)
}
for(new i=0; i<len; i++){
if((g_p_password[id][i] < 'a' || g_p_password[id][i] > 'z') &&
(g_p_password[id][i] < 'A' || g_p_password[id][i] > 'Z') &&
(g_p_password[id][i] < '0' || g_p_password[id][i] > '9') &&
g_p_password[id][i] != '-' && g_p_password[id][i] != '_'){
incorrect_login_data(id)
}
}
for(new i=1; i<=g_max_players; i++){
if(i==id || !is_user_connected(i))
continue
if(equal(g_p_username[i], g_p_username[id])){
client_print(id, print_chat, "[RPG mod]Ошибка: имя пользователя уже используется.")
client_print(id, print_console, "[RPG mod]Ошибка: имя пользователя уже используется.")
g_p_username[id] = ""
g_p_password[id] = ""
return PLUGIN_HANDLED
}
}
g_p_login_status[id] = REG_TRY
g_p_data_loaded[id] = DATA_NOT_LOADED
data_load(id)
return PLUGIN_HANDLED
}
#define TID_UPDATE_HP 437345
public fix_0hp(msg_id, msg_dest, id){
if(!is_user_alive(id))
return
if(!task_exists(TID_UPDATE_HP+id))
set_task(0.1, "update_hp", TID_UPDATE_HP+id)
if(get_msg_arg_int(1) > 255)
set_msg_arg_int(1, 0, 255)
}
public update_hp(tid){
update_StatusText(tid-TID_UPDATE_HP)
}
public force_drop_upgrades(id){
for(new i=0; i<MAX_UPGS; i++){
g_p_credits[id] += as_sum_fn(g_p_upg[id][i], g_upg_sp[i], g_upg_ip[i])
g_p_upg[id][i] = 0
upgrade_change(id, i)
}
}
public drop_upg_cmd(id, level, cid){
static players[MAX_PLAYERS], pnum, arg[32], tmp, i, name[32]
if (!cmd_access(id, level, cid, 2))
return PLUGIN_HANDLED
read_argv(1, arg, 31)
pnum = 0
if(equali(arg, "@all")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i))
players[pnum++] = i
}else if(equali(arg, "@t")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_team(i)==1)
players[pnum++] = i
}else if(equali(arg, "@ct")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_team(i)==2)
players[pnum++] = i
}else if(arg[0] == '#'){
tmp = str_to_num(arg[1])
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_userid(i)==tmp)
players[pnum++] = i
}else{
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i)){
get_user_name(i, name, 31)
if(equal(name, arg)){
pnum = 0
players[pnum++] = i
break
}else if(contain(name, arg)>-1){
players[pnum++] = i
}
}
}
if(pnum<=0){
client_print(id, print_console, "[RPG mod]Ошибка: цель не найдена")
return PLUGIN_HANDLED
}
for(i=0; i<pnum; i++){
force_drop_upgrades(players[i])
}
get_user_name(id, name, 31)
log_amx("ADMIN %s used cmd [ amx_rpg_drop_upg %s ], affected players: %d", name, arg, pnum)
client_print(0, print_chat, "ADMIN %s: [drop upgrades: %s], affected players: %d", name, arg, pnum)
return PLUGIN_HANDLED
}
public set_upg_cmd(id, level, cid){
static players[MAX_PLAYERS], pnum, arg[32], args[63], tmp, i, j, name[32]
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED
read_argv(1, arg, 31)
pnum = 0
if(equali(arg, "@all")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i))
players[pnum++] = i
}else if(equali(arg, "@t")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_team(i)==1)
players[pnum++] = i
}else if(equali(arg, "@ct")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_team(i)==2)
players[pnum++] = i
}else if(arg[0] == '#'){
tmp = str_to_num(arg[1])
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_userid(i)==tmp)
players[pnum++] = i
}else{
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i)){
get_user_name(i, name, 31)
if(equal(name, arg)){
pnum = 0
players[pnum++] = i
break
}else if(contain(name, arg)>-1){
players[pnum++] = i
}
}
}
if(pnum<=0){
client_print(id, print_console, "[RPG mod]Ошибка: цель не найдена")
return PLUGIN_HANDLED
}
new cost, lvl_req, upgs[MAX_UPGS]
read_argv(2, arg, 31)
for(i=0; i<MAX_UPGS; i++){
if(!g_upg_enabled[i]){
upgs[i] = 0
continue
}
if(arg[i] >= '0' && arg[i] <= '9')
upgs[i] = arg[i]-'0'
else if(arg[i] >= 'a' && arg[i] <= 'z')
upgs[i] = arg[i]-'a'+10
else if(arg[i] >= 'A' && arg[i] <= 'Z')
upgs[i] = arg[i]-'A'+10
else
upgs[i] = 0
if(upgs[i] < 0)
upgs[i] = 0
if(upgs[i] > g_upg_maxlvl[i])
upgs[i] = g_upg_maxlvl[i]
cost += as_sum_fn(upgs[i], g_upg_sp[i], g_upg_ip[i])
}
lvl_req = cost / CREDITS_PER_LVL
for(i=0; i<pnum; i++){
for(j=0; j<MAX_UPGS; j++){
g_p_upg[players[i]][j] = upgs[j]
upgrade_change(players[i], j)
}
if(g_p_level[players[i]] < lvl_req){
g_p_level[players[i]] = lvl_req
g_p_xp[players[i]] = as_sum_fn(lvl_req, XP_START, XP_INC)
g_p_progress[players[i]] = 0
}
g_p_credits[players[i]] = g_p_level[players[i]]*CREDITS_PER_LVL - cost
data_save(players[i])
}
read_args(args, 63)
get_user_name(id, name, 31)
log_amx("ADMIN %s used cmd [ amx_rpg_set_upgs %s ], affected players: %d", name, args, pnum)
client_print(0, print_chat, "ADMIN %s: [set upgrades: %s], affected players: %d", name, args, pnum)
return PLUGIN_HANDLED
}
public change_lvl_cmd(id, level, cid){
static players[MAX_PLAYERS], pnum, arg[32], args[63], tmp, amount, i, j, name[32]
if (!cmd_access(id, level, cid, 4))
return PLUGIN_HANDLED
read_argv(1, arg, 31)
pnum = 0
if(equali(arg, "@all")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i))
players[pnum++] = i
}else if(equali(arg, "@t")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_team(i)==1)
players[pnum++] = i
}else if(equali(arg, "@ct")){
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_team(i)==2)
players[pnum++] = i
}else if(arg[0] == '#'){
tmp = str_to_num(arg[1])
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i) && get_user_userid(i)==tmp)
players[pnum++] = i
}else{
for(i=1; i<=g_max_players; i++)
if(is_user_connected(i)){
get_user_name(i, name, 31)
if(equal(name, arg)){
pnum = 0
players[pnum++] = i
break
}else if(contain(name, arg)>-1){
players[pnum++] = i
}
}
}
if(pnum<=0){
client_print(id, print_console, "[RPG mod]Ошибка: цель не найдена")
return PLUGIN_HANDLED
}
read_argv(3, arg, 31)
amount = str_to_num(arg)
read_argv(2, arg, 1)
if(amount<0 || (amount==0 && arg[0]!='=')){
client_print(id, print_console, "[RPG mod]Ошибка: недопестимое количество.")
return PLUGIN_HANDLED
}
switch(arg[0]){
case '+': { //increases level and credits
for(i=0; i<pnum; i++){
g_p_level[players[i]] += amount
g_p_xp[players[i]] = as_sum_fn(g_p_level[players[i]], XP_START, XP_INC)
g_p_credits[players[i]] += amount * CREDITS_PER_LVL
g_p_progress[players[i]] = 0
set_default_lvl_upg(players[i])//will not set lvl if player has lvl > default lvl
data_save(players[i])
}
}
case '-': { //reduces level and credits
for(i=0; i<pnum; i++){
g_p_level[players[i]] -= amount
g_p_xp[players[i]] = as_sum_fn(g_p_level[players[i]], XP_START, XP_INC)
g_p_credits[players[i]] -= amount * CREDITS_PER_LVL
g_p_progress[players[i]] = 0
if(g_p_credits[players[i]] < 0)
force_drop_upgrades(players[i])
if(g_p_credits[players[i]] < 0)
g_p_level[players[i]] = 0 //will reset to default in set_default_lvl_upg
set_default_lvl_upg(players[i])//will not set lvl if player has lvl > default lvl
data_save(players[i])
}
}
case '=': { //set level and credits (all previous upg sell penalty is gone)
for(i=0; i<pnum; i++){
g_p_level[players[i]] = amount
g_p_xp[players[i]] = as_sum_fn(g_p_level[players[i]], XP_START, XP_INC)
g_p_credits[players[i]] = amount * CREDITS_PER_LVL
g_p_progress[players[i]] = 0
for(j=0; j<MAX_UPGS; j++)
g_p_credits[players[i]] -= as_sum_fn(g_p_upg[players[i]][j], g_upg_sp[j], g_upg_ip[j])
if(g_p_credits[players[i]] < 0)
force_drop_upgrades(players[i])
set_default_lvl_upg(players[i])//will not set lvl if player has lvl > default lvl
data_save(players[i])
}
}
default: {
client_print(id, print_console, "[RPG mod]Error: invalid 2nd argument - must be - or + or = ")
return PLUGIN_HANDLED
}
}
read_args(args, 63)
get_user_name(id, name, 31)
log_amx("ADMIN %s used cmd [ amx_rpg_lvl %s ], affected players: %d", name, args, pnum)
client_print(0, print_chat, "ADMIN %s: [level change: %s], affected players: %d", name, args, pnum)
return PLUGIN_HANDLED
}
/*
################################################################################
#########
################################################################################
#########
################################################################################
#########
################################################################################
#########
*/
public block_denial(){ //called on game commencing and round restart
g_block_denial = true
}
////////////////////////////////check_cfg_file() UNFINISHED
public check_cfg_file(){
new cfgdir[128], cache[256], fh
get_configsdir(cfgdir, 127)
format(cfgdir, 127, "%s%s", cfgdir, "/rpg_mod")
if(!dir_exists(cfgdir)){
log_amx("Config dir does not exist (%s), creating...", cfgdir)
if(mkdir(cfgdir)!=0){
log_amx("Error: Could not create dir (%s).", cfgdir)
return
}
}
formatex(cache, 255, "%s%s", cfgdir, "/rpg_mod.cfg")
if(!file_exists(cache)){
log_amx("Config file does not exist: (%s), creating...", cache)
fh = fopen(cache, "wt")
if(!fh){
log_amx("Error: Could not open file for writing (%s).", cache)
return
}else{
fputs(fh, "// RPG Mod Configuration File^n")
fputs(fh, "echo Executing RPG Mod Configuration File^n^n")
fputs(fh, "rpgm_save 1^t^t^t//1 = save data, 0 = don't save data^n")
fputs(fh, "rpgm_saveby 1^t^t^t//1 = STEAMID, 2 = ip, 3 = name^n")
fputs(fh, "rpgm_savedb 1^t^t^t//1 = nVault, 2 = MySql^n^n")
fputs(fh, "rpgm_upgs 111111111111^n")
fputs(fh, "rpgm_xp_mult 1.0^n")
fclose(fh)
}
}
server_cmd("exec %s", cache)
}
//xp needed to gain lvls, upgrades cost are elements of arithmetic sequence
//so I need functions to get number of elements from sum
//and sum from number of elements
public as_num_fs(sum, base, diff){ //returns number of elements
static l, r, mid, bool:found
if(sum<10000)
//this formula is not working with high values of sum (getting out of int max limit)
return (sqroot((2*base-diff)*(2*base-diff) + 8*diff*sum) - (2*base-diff))/(2*diff)
if(sum<base)
return 0
r = 1
//binary search - not as fast as formula above but still faster than linera search...
while( ( 2*base + diff*(r-1) )*r/2 < sum)
r = r*2
l = r/2
//now the number we are looking for is somewhere between l and r
found = false
while(!found){
mid = (l+r)/2
if(( 2*base + diff*(mid-1) )*mid/2 > sum)
r = mid-1
else if(( 2*base + diff*mid )*(mid+1)/2 <= sum)
l = mid+1
else
found = true
}
return mid
}
public as_sum_fn(num, base, diff) //returns sum of elements
return num*(base*2 + diff*(num-1))/2
public data_save_all(){
if(g_db_status != DB_READY)
return
for(new id=1; id<=g_max_players; id++){
if(is_user_connected(id) && (g_p_authorized[id] || g_saveby != SAVEBY_STEAMID))
data_save(id)
}
}
public data_load_all(){
for(new id=1; id<=g_max_players; id++){
if((is_user_connected(id) || is_user_connecting(id))
&& (g_p_authorized[id] || g_saveby != SAVEBY_STEAMID))
data_load(id)
}
}
public data_save(id){
static nv_hnd, data[256], cache[512], key[64], i, saveby, pos
if(g_db_status != DB_READY || g_p_data_loaded[id] == DATA_NOT_LOADED)
return
if(g_p_login_status[id] == REG_DONE){
saveby = SAVEBY_LOGIN
i = -3
}else{
saveby = g_saveby
i = -2
}
if(is_user_bot(id)){
if(g_bot_savedata == 0)
return
else
saveby = SAVEBY_BOT
}
switch(saveby){
case SAVEBY_STEAMID: copy(key, 31, g_p_authid[id])
case SAVEBY_IP: copy(key, 31, g_p_ip[id])
case SAVEBY_NAME:{
if(g_savedb == SAVEDB_NVAULT)
copy(key, 31, g_p_name[id])
else
SQL_QuoteString(g_sql_connection, key, 63, g_p_name[id])
}
case SAVEBY_LOGIN: copy(key, 31, g_p_username[id])
case SAVEBY_BOT:{ //
if(g_savedb == SAVEDB_NVAULT)
copy(key, 31, g_p_name[id])
else
SQL_QuoteString(g_sql_connection, key, 63, g_p_name[id])
}
}
pos = 0
data = ""
for(; i<MAX_UPGS; i++){
switch(i){
case -3: pos += formatex(data[pos], 255-pos, "%s ", g_p_password[id])
case -2: pos += formatex(data[pos], 255-pos, "%d ", g_p_xp[id])
case -1: pos += formatex(data[pos], 255-pos, "%d ", g_p_credits[id])
default: pos += formatex(data[pos], 255-pos, "%d ", as_sum_fn(g_p_upg[id][i], g_upg_sp[i], g_upg_ip[i]))
}
}
if(g_savedb == SAVEDB_NVAULT){
nv_hnd = nvault_open(g_saveby_name[saveby])
if(nv_hnd == INVALID_HANDLE){
log_amx("Failed to open nVault %s.", g_saveby_name[saveby])
g_p_login_status[id] = REG_NONE
return
}
nvault_set(nv_hnd, key, data)
g_p_temp_xp[id] = 0
nvault_close(nv_hnd)
}else{ // g_savedb == SAVEDB_MYSQL
formatex(cache, 511, "REPLACE INTO %s (db_key, data) VALUES ('%s', '%s');", g_saveby_name[saveby], key, data)
new temp[2]
temp[0] = id
SQL_ThreadQuery(g_sql_tuple, "handle_sql_save", cache, temp, 2)
}
if(saveby == SAVEBY_LOGIN){
data_delete(id, g_saveby)
}
}
public handle_sql_save(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
if(g_db_status != DB_READY)
return PLUGIN_HANDLED
if(FailState){
log_amx("SQL Error: %s (%d)", Error, Errcode)
return PLUGIN_HANDLED
}
g_p_temp_xp[Data[0]] = 0
return PLUGIN_CONTINUE
}
public data_load(id){
static nv_hnd, data[2], cache[256], ts, ret, key[32], i, saveby
if(g_db_status != DB_READY || g_p_data_loaded[id] != DATA_NOT_LOADED
|| g_p_login_status[id] == REG_DONE)
return
if(g_p_login_status[id] == REG_TRY){
saveby = SAVEBY_LOGIN
i = -3
}else{
i = -2
saveby = g_saveby
}
if(is_user_bot(id)){
if(g_bot_savedata == 0)
return
else
saveby = SAVEBY_BOT
}
switch(saveby){
case SAVEBY_STEAMID: copy(key, 31, g_p_authid[id])
case SAVEBY_IP: copy(key, 31, g_p_ip[id])
case SAVEBY_NAME: {
if(g_savedb == SAVEDB_NVAULT)
copy(key, 31, g_p_name[id])
else
SQL_QuoteString(g_sql_connection, key, 63, g_p_name[id])
}
case SAVEBY_LOGIN: copy(key, 31, g_p_username[id])
case SAVEBY_BOT: {
if(g_savedb == SAVEDB_NVAULT)
copy(key, 31, g_p_name[id])
else
SQL_QuoteString(g_sql_connection, key, 63, g_p_name[id])
}
}
if(g_savedb == SAVEDB_NVAULT){
nv_hnd = nvault_open(g_saveby_name[saveby])
if(nv_hnd == INVALID_HANDLE){
log_amx("Failed to open nVault %s.", g_saveby_name[saveby])
client_print(id, print_chat, "[RPG mod]Ошибка: не удалось подключиться к базе данных.")
client_print(id, print_console, "[RPG mod]Ошибка: не удалось подключиться к базе данных.")
g_p_login_status[id] = REG_NONE
return
}
ret = nvault_lookup(nv_hnd, key, cache, 255, ts)
nvault_close(nv_hnd)
if(ret==0){
g_p_data_loaded[id] = DATA_NOT_FOUND
if(g_p_login_status[id] == REG_TRY){
g_p_login_status[id] = REG_DONE
data_save(id) //lets reserve this username
client_print(id, print_chat, "[RPG mod] Вы успешно зарегистрировались")
client_print(id, print_console, "[RPG mod] Вы успешно зарегистрировались")
g_p_pw_hidden[id] = true
set_default_lvl_upg(id)
}
}else{
decode_data_str(id, cache, i)
}
}else{ // g_savedb == SAVEDB_MYSQL
data[0] = id
data[1] = i
g_p_data_loaded[id] = DATA_LOADING
format(cache, 255, "SELECT data FROM %s WHERE db_key = '%s'", g_saveby_name[saveby], key)
SQL_ThreadQuery(g_sql_tuple, "handle_sql_load", cache, data, 2)
}
}
public handle_sql_load(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
static id, i, cache[256]
if(g_db_status != DB_READY)
return PLUGIN_HANDLED
if(FailState){
log_amx("SQL Error: %s (%d)", Error, Errcode)
return PLUGIN_HANDLED
}
id = Data[0]
i = Data[1]
if(SQL_MoreResults(Query)){
SQL_ReadResult(Query, 0, cache, 255)
decode_data_str(id, cache, i)
}else{
//first time connect
g_p_data_loaded[id] = DATA_NOT_FOUND
if(g_p_login_status[id] == REG_TRY){
g_p_login_status[id] = REG_DONE
data_save(id) //lets reserve this username
client_print(id, print_chat, "[RPG mod] Вы успешно зарегистрировались")
client_print(id, print_console, "[RPG mod] Вы успешно зарегистрировались")
g_p_pw_hidden[id] = true
set_default_lvl_upg(id)
}
}
return PLUGIN_CONTINUE
}
public decode_data_str(id, data[], i){
static temp[32], num
for(; i<MAX_UPGS; i++){
strbreak(data, temp, 31, data, 255)
remove_quotes(temp)
switch(i){
case -3:{
if(!equal(temp, g_p_password[id])){
client_print(id, print_chat, "[RPG mod]Ошибка: имя пользователя найдено в базе данных, неправильный пароль.")
client_print(id, print_console, "[RPG mod]Ошибка: имя пользователя найдено в базе данных, неправильный пароль.")
g_p_username[id] = ""
g_p_password[id] = ""
g_p_login_status[id] = REG_NONE
g_p_data_loaded[id] = DATA_LOADED
set_default_lvl_upg(id)
return
}
client_print(id, print_chat, "[RPG mod] Вы успешно залогинились")
client_print(id, print_console, "[RPG mod] Вы успешно залогинились")
g_p_pw_hidden[id] = true
}
case -2:{
g_p_xp[id] = str_to_num(temp)
g_p_level[id] = as_num_fs(g_p_xp[id], XP_START, XP_INC)
g_p_progress[id] = 100-(as_sum_fn(g_p_level[id]+1, XP_START, XP_INC)-g_p_xp[id])*100/(XP_START+XP_INC*g_p_level[id])
}
case -1: g_p_credits[id] = str_to_num(temp)
default:{
num = str_to_num(temp)
g_p_upg[id][i] = as_num_fs(num, g_upg_sp[i], g_upg_ip[i])
if(g_p_upg[id][i] > g_upg_maxlvl[i])
g_p_upg[id][i] = g_upg_maxlvl[i]
if(!g_upg_enabled[i])
g_p_upg[id][i] = 0
upgrade_change(id, i)
g_p_credits[id] += num - as_sum_fn(g_p_upg[id][i], g_upg_sp[i], g_upg_ip[i])
}
}
}
g_p_data_loaded[id] = DATA_LOADED
if(g_p_login_status[id] == REG_TRY)
g_p_login_status[id] = REG_DONE
set_default_lvl_upg(id)
}
public data_delete(id, saveby){
static nv_hnd, key[64], cache[128]
if(g_db_status != DB_READY)
return
switch(saveby){
case SAVEBY_STEAMID: copy(key, 31, g_p_authid[id])
case SAVEBY_IP: copy(key, 31, g_p_ip[id])
case SAVEBY_NAME: {
if(g_savedb == SAVEDB_NVAULT)
copy(key, 31, g_p_name[id])
else
SQL_QuoteString(g_sql_connection, key, 63, g_p_name[id])
}
case SAVEBY_LOGIN:{
copy(key, 31, g_p_username[id])
g_p_username[id] = ""
g_p_password[id] = ""
}
case SAVEBY_BOT: {
if(g_savedb == SAVEDB_NVAULT)
copy(key, 31, g_p_name[id])
else
SQL_QuoteString(g_sql_connection, key, 63, g_p_name[id])
}
}
if(g_savedb == SAVEDB_NVAULT){
nv_hnd = nvault_open(g_saveby_name[saveby])
if(nv_hnd == -1){
log_amx("Failed to open nvault")
return
}
nvault_remove(nv_hnd, key)
nvault_close(nv_hnd)
}else{ //g_savedb == SAVEDB_MYSQL
formatex(cache, 127, "DELETE from %s WHERE db_key = '%s';", g_saveby_name[saveby], key)
SQL_ThreadQuery(g_sql_tuple, "handle_sql_delete", cache)
}
}
public handle_sql_delete(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
if(g_db_status != DB_READY)
return PLUGIN_HANDLED
if(FailState){
log_amx("SQL Error: %s (%d)", Error, Errcode)
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public event_new_round(){
g_freezetime = true
if(g_block_denial){
g_block_denial = false
for(new id=1; id<=g_max_players; id++){
g_c_denial[id] = DENIAL_BLOCK
}
}
for(new id=1; id<=g_max_players; id++){
g_c_regen[id] = 0
g_c_arm_regen[id] = 0
g_c_resup[id] = 0
g_p_next_lj[id] = 0.0
g_p_jump[id] = false
g_c_frost[id] = 0
g_c_ice[id] = 0
g_c_impulse[id] = 0
g_c_medic[id] = 0
}
if(g_frequent_save==1)
data_save_all()
}
public logevent_round_start(){
g_freezetime = false
}
public update_StatusText(id){
static cache[512]
if(!is_user_alive(id) || !g_user_control || (g_in_team && g_in_team != g_p_team[id])
|| !g_p_settings[id][SETT_INFO_UNDER_CHAT])
return
format(cache, 511, "[%d HP][Level: %d][Progress: %d%s][Credits: %d]", get_user_health(id), g_p_level[id], g_p_progress[id], "%%", g_p_credits[id])
message_begin(MSG_ONE_UNRELIABLE, g_msgStatusText, {0,0,0}, id)
write_byte(0)
write_string(cache)
message_end()
}
public event_CurWeapon(id){
reset_player_speed(id)
}
public player_death(id){
static attacker, victim
attacker = read_data(1)
victim = read_data(2)
if(!is_user_alive(victim)){
g_p_alive[victim] = false
}
g_p_weap_num[victim] = 0
get_user_weapons(victim, g_p_weap[victim], g_p_weap_num[victim])
g_p_defkit[victim] = cs_get_user_defuse(victim)
g_p_armor[victim] = cs_get_user_armor(victim, g_p_atype[victim])
if(g_p_upg[victim][UPG_DENIAL] && g_c_denial[victim] != DENIAL_BLOCK && !(g_in_team && g_in_team != g_p_team[id]))
g_c_denial[victim] = DENIAL_NEXT_SPAWN
if(attacker == victim)
return
if(attacker < 1 || attacker > g_max_players)
return
if(victim < 1 || victim > g_max_players)
return
if(cs_get_user_team(victim)==cs_get_user_team(attacker))
return
fn_addxp(attacker, fn_calcxp(CXT_KILL, attacker, victim, 0))
}
public fwd_CmdStart(id, uc_handle, seed){
if(!is_user_alive(id))
return FMRES_IGNORED
g_p_buttons[id] = get_uc(uc_handle,UC_Buttons)
return FMRES_IGNORED;
}
public player_PreThink(id){
static Float:ftmp, Float:angle[3], sum, s, s2
if(pev(id, pev_button)&IN_JUMP && !(pev(id, pev_oldbuttons)&IN_JUMP)
&& pev(id, pev_flags)&FL_ONGROUND){
g_p_jump[id] = true
}
if(pev(id, pev_button)&IN_JUMP && !(pev(id, pev_oldbuttons)&IN_JUMP)
&& !(pev(id, pev_flags)&FL_ONGROUND)){
g_p_jump[id] = false
}
if(is_user_alive(id)){
pev(id, pev_fuser2, ftmp)
ftmp -= 0.001*g_p_upg[id][UPG_LJ]*g_p_upg[id][UPG_LJ]*ftmp
if(ftmp<0.0)
ftmp=0.0
if(g_c_ice[id]>0 || g_c_frost[id]>0){
pev(id, pev_v_angle, angle)
if(g_c_ice[id]>0){
ftmp = 1000.0*sqroot(g_c_ice[id]-1)
s = 2*sqroot(g_c_ice[id])
s2= 1
sum = s+s2
}else{
ftmp = 500.0
s = 3
s2 = 2
sum = s+s2
}
g_p_angle[id][0] = g_p_angle[id][0]*s/sum + angle[0]*s2/sum
if(angle[1]<-90.0 && g_p_angle[id][1]>90.0)
g_p_angle[id][1] = (g_p_angle[id][1]-360.0)*s/sum + angle[1]*s2/sum
else if(angle[1]>90.0 && g_p_angle[id][1]<-90.0)
g_p_angle[id][1] = (g_p_angle[id][1]+360.0)*s/sum + angle[1]*s2/sum
else
g_p_angle[id][1] = g_p_angle[id][1]*s/sum + angle[1]*s2/sum
if(g_p_angle[id][1]<-180.0)
g_p_angle[id][1] += 360.0
else if(g_p_angle[id][1]>180.0)
g_p_angle[id][1] -= 360.0
set_pev(id, pev_angles, g_p_angle[id])
set_pev(id, pev_fixangle, 1)
}
set_pev(id, pev_fuser2, ftmp)
}
return FMRES_IGNORED
}
public player_PostThink(id){
static Float:velocity[MAX_PLAYERS+1][3], Float:land_time[MAX_PLAYERS+1]
static Float:tmp_time, Float:tmp_speed, Float:lj_max_speed, Float:weap_speed
static Float:xy_speed[MAX_PLAYERS+1], on_ground[MAX_PLAYERS+1], tmp_on_ground
pev(id, pev_velocity, velocity[id])
tmp_on_ground = pev(id, pev_flags)&FL_ONGROUND
if(on_ground[id] && !tmp_on_ground){//player just jumped/lost ground/fell
if(g_p_jump[id]){
g_p_jump[id] = false
global_get(glb_time, tmp_time)
tmp_speed = floatsqroot(velocity[id][0]*velocity[id][0] + velocity[id][1]*velocity[id][1])
velocity[id][0] = velocity[id][0]/tmp_speed
velocity[id][1] = velocity[id][1]/tmp_speed
if(tmp_time-land_time[id]>0.08 || tmp_speed < 200.0 || g_p_upg[id][UPG_BHOP] < 2){
xy_speed[id] = tmp_speed
}
weap_speed = g_weap_speed[get_user_weapon(id)]
lj_max_speed = weap_speed*(1.0+0.2*g_p_upg[id][UPG_LJ])
if(xy_speed[id]<lj_max_speed){
xy_speed[id] = xy_speed[id]*(1.0+0.2*g_p_upg[id][UPG_LJ])
if(xy_speed[id]>lj_max_speed){
xy_speed[id] = lj_max_speed
}
}
if(g_c_frost[id] > 0 && xy_speed[id] > weap_speed){
xy_speed[id] -= xy_speed[id]*0.2
}
velocity[id][0] = velocity[id][0]*xy_speed[id]
velocity[id][1] = velocity[id][1]*xy_speed[id]
if(!g_in_team || g_in_team == g_p_team[id])
if(velocity[id][0] < 2000.0 && velocity[id][0] > -2000.0
&& velocity[id][1] < 2000.0 && velocity[id][1] > -2000.0)
set_pev(id, pev_velocity, velocity[id])
}
on_ground[id] = tmp_on_ground
}else if(!on_ground[id] && tmp_on_ground){ //player just landed
global_get(glb_time, land_time[id])
on_ground[id] = tmp_on_ground
}
if(g_p_upg[id][UPG_BHOP] && pev(id, pev_flags)&FL_ONGROUND && pev(id, pev_button)&IN_JUMP
&& g_c_ice[id]<=0 && (!g_in_team || g_in_team == g_p_team[id])){
set_pev(id, pev_oldbuttons, pev(id, pev_oldbuttons) & ~IN_JUMP)
set_pev(id, pev_gaitsequence, 6)
set_pev(id, pev_frame, 0.0)
}
if(!tmp_on_ground){
xy_speed[id] = floatsqroot(velocity[id][0]*velocity[id][0] + velocity[id][1]*velocity[id][1])
}
return FMRES_IGNORED
}
public damage_event(id){
static weapon, bodypart, attacker, dmg, health, tmp
attacker = get_user_attacker(id, weapon, bodypart)
if(attacker<1 || attacker>32 || id<1 || id>32 || g_p_team[id]==g_p_team[attacker] || id==attacker)
return
dmg = read_data(2)
fn_addxp(attacker, fn_calcxp(CXT_DMG, attacker, id, dmg))
health = get_user_health(attacker)
if(g_p_upg[id][UPG_IMPULSE] && (!g_in_team || g_in_team == g_p_team[id])){
g_c_impulse[id] = 50
reset_player_speed(id)
}
if(g_in_team && g_in_team != g_p_team[attacker])
return
if(g_p_upg[attacker][UPG_VAMP] && health<g_p_maxhealth[attacker]){
tmp = get_user_health(id)
if(tmp>0)
tmp = 0
tmp += dmg
health += floatround(tmp*g_p_upg[attacker][UPG_VAMP]*0.05)
if(health<g_p_maxhealth[attacker])
set_user_health(attacker, health)
else
set_user_health(attacker, g_p_maxhealth[attacker])
}
if(g_p_upg[attacker][UPG_ICESTAB] && weapon==CSW_KNIFE
&& !(g_p_buttons[attacker] & IN_ATTACK) && (g_p_buttons[attacker] & IN_ATTACK2)){
if(g_c_ice[id]<10*g_p_upg[attacker][UPG_ICESTAB]){
g_c_ice[id] = 10*g_p_upg[attacker][UPG_ICESTAB] + 3
g_c_ice[id] -= g_c_ice[id]*100*g_p_upg[id][UPG_ANTI_ICESTAB]/(g_upg_maxlvl[UPG_ANTI_ICESTAB]*100)
pev(id, pev_v_angle, g_p_angle[id])
}
}
if(g_p_upg[attacker][UPG_FROST] && ( weapon==CSW_P228 || weapon==CSW_ELITE
|| weapon==CSW_FIVESEVEN || weapon==CSW_USP || weapon==CSW_GLOCK18 || weapon==CSW_DEAGLE )){
if(g_c_frost[id]<g_p_upg[attacker][UPG_FROST]){
g_c_frost[id] = g_p_upg[attacker][UPG_FROST] + 3
g_c_frost[id] -= g_c_frost[id]*100*g_p_upg[id][UPG_ANTI_FROSTKNIFE]/(g_upg_maxlvl[UPG_ANTI_FROSTKNIFE]*100)
pev(id, pev_v_angle, g_p_angle[id])
}
}
}
public reset_player_speed(id){
static Float:speed, weap
if(g_freezetime)
return
weap = get_user_weapon(id)
speed = g_weap_speed[weap]
if(g_c_impulse[id]>0){
speed += speed*0.10*g_p_upg[id][UPG_IMPULSE]
}
set_user_maxspeed(id, speed)
}
public select_random_upgrades(id){
static upg_list[MAX_UPGS], last, i, upg
for(i = 0; i<g_enabled_upgs; i++)
upg_list[i] = g_enabled_list[i]
last = g_enabled_upgs-1
while(g_p_credits[id] >= 0){
for(i=last; i>=0; i--) //remove maxed upgs from list
if(g_p_upg[id][ upg_list[i] ] >= g_upg_maxlvl[ upg_list[i] ]){
upg_list[i] = upg_list[last]
last--
}
if(last<0)
return
upg = upg_list[ random(last+1) ]
g_p_credits[id] -= g_upg_sp[upg] + g_upg_ip[upg]*g_p_upg[id][upg]
g_p_upg[id][upg]++
upgrade_change(id, upg)
}
}
public player_spawn(id){
static temp
if(is_user_alive(id)){
g_p_team[id] = get_user_team(id)
g_c_regen[id] = 0
g_c_arm_regen[id] = 0
g_c_resup[id] = 0
g_c_frost[id] = 0
g_c_ice[id] = 0
g_c_impulse[id] = 0
g_c_medic[id] = 0
g_p_alive[id] = true
if(g_p_upg[id][UPG_STEALTH]){
temp = 255-40*g_p_upg[id][UPG_STEALTH]
if(temp<0)
temp=0
if(g_in_team && g_in_team != g_p_team[id])
temp=255
set_user_rendering(id, 0, 0, 0, 0, kRenderTransAlpha, temp)
}
if(g_in_team && g_in_team != g_p_team[id])
return
if(g_p_settings[id][SETT_MENU_ON_SPAWN])
set_task(0.5, "menu_main", id)
if(is_user_bot(id) && get_pcvar_num(pc_bot_buy_upgrades)==1){
if(g_p_credits[id]>=0){
select_random_upgrades(id)
}
}
if(g_c_denial[id] == DENIAL_BLOCK){
g_c_denial[id] = 0
}
if(g_c_denial[id] == DENIAL_NEXT_SPAWN){
g_c_denial[id] = DENIAL_START
}
set_user_health(id, g_p_maxhealth[id])
}
}
public Player_TakeDamage(victim, inflictor, attacker, Float:damage, damagebits) {
static classname[10], Float:velocity[3]
if(attacker==victim || !is_user_connected(attacker))
return HAM_IGNORED
if(inflictor == attacker){
switch(get_user_weapon(attacker)){
case CSW_AWP, CSW_SCOUT: {
if(random_float(0.0, 1.0) < 1.0*g_p_upg[attacker][UPG_BEE_STING]/g_upg_maxlvl[UPG_BEE_STING]){
pev(victim, pev_velocity, velocity)
if(velocity[2] < 300.0){
velocity[2] += 300.0
if(velocity[2] < 300.0)
velocity[2] = 300.0
set_pev(victim, pev_velocity, velocity)
}
}
damage += damage*g_p_upg[attacker][UPG_APWSCOUT_DMG]*0.1
}
default: damage += damage*g_p_upg[attacker][UPG_WPN_DMG]*0.04
}
}else if(pev_valid(inflictor)){
pev(inflictor, pev_classname, classname, sizeof(classname)-1)
if(equal(classname, "grenade"))
damage += damage*g_p_upg[attacker][UPG_HE_DMG]*1.0
}
damage -= damage*g_p_upg[victim][UPG_DMG_REDUCE]*0.03
SetHamParamFloat(4, damage)
return HAM_HANDLED
}
public update_vars(){
static temp[MAX_UPGS+1], i, j, bool:upg_changed
g_mradius = 300.0
g_sq_mradius = g_mradius*g_mradius
g_user_control = get_pcvar_num(pc_user_control)
g_in_team = get_pcvar_num(pc_in_team)
g_xp_multipler = get_pcvar_float(pc_xp_mult)
g_admin_xp_multipler = get_pcvar_float(pc_admin_xp_mult)
g_vip_xp_multipler = get_pcvar_float(pc_vip_xp_mult)
if(g_xp_multipler > MAX_XP_MULTI)
g_xp_multipler = MAX_XP_MULTI
if(g_xp_multipler < 0.0)
g_xp_multipler = 0.0
if(g_admin_xp_multipler > MAX_XP_MULTI)
g_admin_xp_multipler = MAX_XP_MULTI
if(g_admin_xp_multipler < 0.0)
g_admin_xp_multipler = 0.0
if(g_vip_xp_multipler > MAX_XP_MULTI)
g_vip_xp_multipler = MAX_XP_MULTI
if(g_vip_xp_multipler < 0.0)
g_vip_xp_multipler = 0.0
g_enabled_upgs = 0
upg_changed = false
get_pcvar_string(pc_upgs, temp, MAX_UPGS)
for(i=0; i<MAX_UPGS; i++){
if(temp[i]!='0'){
if(!g_upg_enabled[i])
upg_changed = true
g_upg_enabled[i] = true
g_enabled_list[g_enabled_upgs] = i
g_enabled_upgs++
}else{
if(g_upg_enabled[i])
upg_changed = true
g_upg_enabled[i] = false
}
}
if(upg_changed){
for(i=1; i<=g_max_players; i++){
if(is_user_connected(i)){
for(j=0; j<MAX_UPGS; j++){
if(!g_upg_enabled[j]){
g_p_credits[i] += as_sum_fn(g_p_upg[i][j], g_upg_sp[j], g_upg_ip[j])
g_p_upg[i][j] = 0
upgrade_change(i, j)
}
}
}
}
}
get_pcvar_string(pc_bot_def_upgs, temp, MAX_UPGS)
g_bot_def_cost = 0
for(i=0; i<MAX_UPGS; i++){
if(!g_upg_enabled[i]){
g_bot_def_upgs[i] = 0
continue
}
if(temp[i] >= '0' && temp[i] <= '9')
g_bot_def_upgs[i] = temp[i]-'0'
else if(temp[i] >= 'a' && temp[i] <= 'z')
g_bot_def_upgs[i] = temp[i]-'a'+10
else if(temp[i] >= 'A' && temp[i] <= 'Z')
g_bot_def_upgs[i] = temp[i]-'A'+10
else
g_bot_def_upgs[i] = 0
if(g_bot_def_upgs[i] < 0)
g_bot_def_upgs[i] = 0
if(g_bot_def_upgs[i] > g_upg_maxlvl[i])
g_bot_def_upgs[i] = g_upg_maxlvl[i]
g_bot_def_cost += as_sum_fn(g_bot_def_upgs[i], g_upg_sp[i], g_upg_ip[i])
}
g_bot_def_lvl_req = g_bot_def_cost / CREDITS_PER_LVL
get_pcvar_string(pc_def_upgs, temp, MAX_UPGS)
g_def_cost = 0
for(i=0; i<MAX_UPGS; i++){
if(!g_upg_enabled[i]){
g_def_upgs[i] = 0
continue
}
if(temp[i] >= '0' && temp[i] <= '9')
g_def_upgs[i] = temp[i]-'0'
else if(temp[i] >= 'a' && temp[i] <= 'z')
g_def_upgs[i] = temp[i]-'a'+10
else if(temp[i] >= 'A' && temp[i] <= 'Z')
g_def_upgs[i] = temp[i]-'A'+10
else
g_def_upgs[i] = 0
if(g_def_upgs[i] < 0)
g_def_upgs[i] = 0
if(g_def_upgs[i] > g_upg_maxlvl[i])
g_def_upgs[i] = g_upg_maxlvl[i]
g_def_cost += as_sum_fn(g_def_upgs[i], g_upg_sp[i], g_upg_ip[i])
}
g_def_lvl_req = g_def_cost / CREDITS_PER_LVL
}
public p_vars_reset_all(){
for(new id=1; id<=g_max_players; id++)
p_vars_reset(id)
}
public p_vars_reset(id){
static i
if(is_user_connected(id) || is_user_connecting(id)){
g_p_xp[id] = 0
g_p_temp_xp[id] = 0
g_p_progress[id] = 0
g_p_credits[id] = 0
g_p_level[id] = 0
for(i=0; i<MAX_UPGS; i++){
g_p_upg[id][i] = 0
}
g_c_regen[id] = 0
g_c_arm_regen[id] = 0
g_p_maxhealth[id] = 100
g_c_resup[id] = 0
g_p_next_lj[id] = 0.0
g_p_jump[id] = false
g_c_frost[id] = 0
g_c_ice[id] = 0
g_c_denial[id] = 0
g_c_impulse[id] = 0
g_c_medic[id] = 0
get_user_name(id, g_p_name[id], 31)
get_user_ip(id, g_p_ip[id], 31)
set_default_lvl_upg(id)
g_p_data_loaded[id] = DATA_NOT_LOADED
}
}
public sql_init(){
new host[32], user[32], pass[32], db[32], err[512], err_code
if(g_db_status == DB_CONNECTING)
return
g_db_status = DB_CONNECTING
get_pcvar_string(pc_sql_host, host, 31)
get_pcvar_string(pc_sql_user, user, 31)
get_pcvar_string(pc_sql_pass, pass, 31)
get_pcvar_string(pc_sql_db, db, 31)
g_sql_tuple = SQL_MakeDbTuple(host, user, pass, db)
if(g_sql_connection != Empty_Handle)
SQL_FreeHandle(g_sql_connection)
g_sql_connection = SQL_Connect(g_sql_tuple,err_code,err,511)
if(g_sql_connection == Empty_Handle){
log_amx("SQL Error: %s (%d)", err, err_code)
g_db_status = DB_NONE
return
}
check_tables()
}
public check_tables(){
static cache[256]
g_sql_tables = 0
for(new i=1; i<6; i++){
//key in tables rpgm_name, rpgm_bot is VARCHAR(64) and VARCHAR(32) in others
//it's because name may contain invalid characters and we need to backquote them
//using SQL_QuoteString, this way name length may increase and be greater than 32
formatex(cache, 255, "CREATE TABLE IF NOT EXISTS %s ( db_key VARCHAR(%d) NOT NULL, data VARCHAR(256), PRIMARY KEY ( db_key ) )", g_saveby_name[i], i==3||i==5?64:32)
SQL_ThreadQuery(g_sql_tuple, "handle_create_table_query", cache)
}
}
public handle_create_table_query(FailState,Handle:Query,Error[],Errcode,Data[],DataSize){
if(g_db_status != DB_CONNECTING)
return PLUGIN_HANDLED
if(FailState){
log_amx("SQL Error: %s (%d)", Error, Errcode)
g_db_status = DB_NONE
g_sql_tables = 0
return PLUGIN_HANDLED
}
g_sql_tables++
if(g_sql_tables == 5){ //sql connected and all tables created
g_db_status = DB_READY
p_vars_reset_all() //######################################## necessary ?
data_load_all()
}
return PLUGIN_CONTINUE
}
public create_timer(){
g_timer_entid = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString,"info_target"))
for(new i=1; i<4; i++){
if(pev_valid(g_timer_entid)){
break
}else{
log_amx("Warning: Failed to create timer entity, retrying(%d)", i)
g_timer_entid = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString,"info_target"))
}
}
if(pev_valid(g_timer_entid)){
set_pev(g_timer_entid, pev_classname, "rpgm_timer")
global_get(glb_time, g_t_time)
set_pev(g_timer_entid, pev_nextthink, g_t_time + UPDATE_INTERVAL)
register_forward(FM_Think,"fwd_Think")
}else{
log_amx("Warning: Failed to create timer entity, using task instead")
set_task(UPDATE_INTERVAL, "timer_cycle", TID_TIMER, "", 0, "b")
}
}
public fwd_Think(Ent){
if(Ent != g_timer_entid)
return FMRES_IGNORED
g_t_time += UPDATE_INTERVAL
set_pev(Ent, pev_nextthink, g_t_time)
timer_cycle()
return FMRES_IGNORED
}
public plugin_unpause(){
if(pev_valid(g_timer_entid)){
global_get(glb_time, g_t_time)
g_t_time += UPDATE_INTERVAL
set_pev(g_timer_entid, pev_nextthink, g_t_time)
}
//CHECK ALL PLAYER DATA ! #############################################
}
public timer_cycle(){
static id, temp, temp2, temp3, i, origin[3], t_origin[3], CsArmorType:atype
static glb_update_cnt, update_cnt[MAX_PLAYERS+1], save_time_cnt
glb_update_cnt--
if(glb_update_cnt<=0){
glb_update_cnt = 30
update_vars()
}
if(g_frequent_save == FREQ_S_INTERVAL && g_db_status == DB_READY){
save_time_cnt--
if(save_time_cnt<=0){
save_time_cnt = 100
id = 1
for(i=2; i<=g_max_players; i++){
if(g_p_temp_xp[i]>g_p_temp_xp[id])
id = i
}
if(g_p_temp_xp[id]>0)
data_save(id)
}
}
for(id=1; id<g_max_players; id++){
if(!is_user_alive(id)){
continue
}
update_cnt[id]--
if(update_cnt[id]<=0){
update_cnt[id] = 10
update_StatusText(id)
}
if(g_c_frost[id]>0){
g_c_frost[id]--
}
if(g_c_ice[id]>0){
g_c_ice[id]--
}
if(g_in_team && g_in_team != g_p_team[id])
continue
if(g_p_upg[id][UPG_REGEN]){
g_c_regen[id]--
if(g_c_regen[id]<=0){
g_c_regen[id] = 10
temp = get_user_health(id)
if(temp<g_p_maxhealth[id]){
temp += g_p_upg[id][UPG_REGEN]
if(temp<g_p_maxhealth[id])
set_user_health(id, temp)
else
set_user_health(id, g_p_maxhealth[id])
}
}
}
if(g_p_upg[id][UPG_ARM_REGEN]){
g_c_arm_regen[id]--
if(g_c_arm_regen[id]<=0){
g_c_arm_regen[id] = 10
temp = cs_get_user_armor(id, CsArmorType:temp2)
if(temp2 == _:CS_ARMOR_NONE)
temp2 = _:CS_ARMOR_KEVLAR
if(temp<100){
temp += g_p_upg[id][UPG_ARM_REGEN]
if(temp<100)
cs_set_user_armor(id, temp, CsArmorType:temp2)
else
cs_set_user_armor(id, 100, CsArmorType:temp2)
}
}
}
if(g_p_upg[id][UPG_RESUP]){
g_c_resup[id]--
if(g_c_resup[id]<=0){
temp = get_user_weapon(id, temp2, temp3)
if(temp<33 && temp3<g_max_bpammo[temp]){
temp3 += g_p_upg[id][UPG_RESUP]
if(temp!=CSW_HEGRENADE && temp!=CSW_C4 && temp!=CSW_SMOKEGRENADE && temp!=CSW_FLASHBANG){
if(temp3<g_max_bpammo[temp]){
cs_set_user_bpammo(id, temp, temp3)
}else{
cs_set_user_bpammo(id, temp, g_max_bpammo[temp])
}
}
}
g_c_resup[id] = 30
}
}
if(g_c_denial[id]>0 && g_c_denial[id] <= DENIAL_START){
g_c_denial[id]--
if(g_c_denial[id]==DENIAL_STRIP){
g_p_has_c4[id] = user_has_weapon(id, CSW_C4)
strip_user_weapons(id)
}
if(g_c_denial[id]==DENIAL_GIVE){
cs_set_user_armor(id, g_p_armor[id], g_p_atype[id])
for(i=0; i<g_p_weap_num[id]; i++){
if(g_p_weap[id][i]!=CSW_C4){
give_item(id, g_gi_names[g_p_weap[id][i]])
if(g_max_bpammo[g_p_weap[id][i]]>1)
cs_set_user_bpammo(id, g_p_weap[id][i], g_max_bpammo[g_p_weap[id][i]])
}
}
if(g_p_has_c4[id] == 1){
give_item(id, "weapon_c4")
cs_set_user_plant(id, 1, 1)
}
if(cs_get_user_team(id) == CS_TEAM_CT){
cs_set_user_defuse(id, g_p_defkit[id])
}
g_c_denial[id] = 0
}
}
if(g_c_impulse[id]>0){
g_c_impulse[id]--
if(g_c_impulse[id] == 0)
reset_player_speed(id)
}
if(g_p_upg[id][UPG_MEDIC]){
g_c_medic[id]--
if(g_c_medic[id]<=0){
g_c_medic[id] = 10
get_user_origin(id, origin)
for(i=1; i<=g_max_players; i++){
if(!is_user_alive(i) || i==id || g_p_team[id]!=g_p_team[i])
continue
get_user_origin(i, t_origin)
t_origin[0] -= origin[0]
t_origin[1] -= origin[1]
t_origin[2] -= origin[2]
if(t_origin[0]*t_origin[0]+t_origin[1]*t_origin[1]+t_origin[2]*t_origin[2]<g_sq_mradius){
temp = get_user_health(i)
if(temp<g_p_maxhealth[i]){
temp += g_p_upg[id][UPG_MEDIC]
if(temp<g_p_maxhealth[i])
set_user_health(i, temp)
else
set_user_health(i, g_p_maxhealth[i])
}else{
temp = cs_get_user_armor(i, atype)
if(atype==CS_ARMOR_NONE)
atype = CS_ARMOR_KEVLAR
if(temp<100){
temp += g_p_upg[id][UPG_MEDIC]
if(temp<100)
cs_set_user_armor(i, temp, atype)
else
cs_set_user_armor(i, 100, atype)
}
}
}
}
} //END if(g_c_medic[id]<=0)
} // END if(g_p_upg[id][UPG_MEDIC])
} //END for(id=1; id<g_max_players; id++)
}
public client_infochanged(id){ //update name
static name[32]
get_user_info(id, "name", name, 31)
if(g_saveby == SAVEBY_NAME && !equal(g_p_name[id], name)){
data_save(id)
p_vars_reset(id)
copy(g_p_name[id], 31, name)
data_load(id)
}
}
public set_default_lvl_upg(id){
static level
if(is_user_bot(id)){
level = get_pcvar_num(pc_bot_start_lvl)
if(g_bot_def_lvl_req > level)
level = g_bot_def_lvl_req
if(g_p_level[id] > level)
return
for(new i=0; i<MAX_UPGS; i++){
g_p_upg[id][i] = g_bot_def_upgs[i]
upgrade_change(id, i)
}
g_p_credits[id] = -g_bot_def_cost
}else{
level = get_pcvar_num(pc_start_lvl)
if(g_def_lvl_req > level)
level = g_def_lvl_req
if(g_p_level[id] > level)
return
for(new i=0; i<MAX_UPGS; i++){
g_p_upg[id][i] = g_def_upgs[i]
upgrade_change(id, i)
}
g_p_credits[id] = -g_def_cost
}
g_p_xp[id] = as_sum_fn(level, XP_START, XP_INC)
g_p_level[id] = as_num_fs(g_p_xp[id], XP_START, XP_INC)
g_p_credits[id] += g_p_level[id] * CREDITS_PER_LVL
g_p_progress[id] = 0
}
public client_connect(id){
client_cmd(id, "hud_centerid 0")
static i
get_rpg_settings(id)
g_p_xp[id] = 0
g_p_temp_xp[id] = 0
g_p_progress[id] = 0
g_p_credits[id] = 0
g_p_level[id] = 0
for(i=0; i<MAX_UPGS; i++){
g_p_upg[id][i] = 0
}
g_c_regen[id] = 0
g_c_arm_regen[id] = 0
g_p_maxhealth[id] = 100
g_c_resup[id] = 0
g_p_next_lj[id] = 0.0
g_p_jump[id] = false
g_c_frost[id] = 0
g_c_ice[id] = 0
g_c_denial[id] = 0
g_c_impulse[id] = 0
g_c_medic[id] = 0
set_default_lvl_upg(id)
g_p_data_loaded[id] = DATA_NOT_LOADED
g_p_authorized[id] = false
g_p_login_status[id] = REG_NONE
get_user_ip(id, g_p_ip[id], 31)
get_user_name(id, g_p_name[id], 31)
g_p_username[id] = ""
g_p_password[id] = ""
if(g_saveby != SAVEBY_STEAMID)
data_load(id)
}
public client_authorized(id){
g_p_authorized[id] = true
get_user_authid(id, g_p_authid[id], 31)
if(g_saveby == SAVEBY_STEAMID)
data_load(id)
}
public client_disconnect(id){
data_save(id)
}
public lvl_diff_mod(attacker, victim){
static alvl, vlvl
alvl = g_p_level[attacker]
vlvl = g_p_level[victim]
if(vlvl > alvl)
return 1 + (vlvl-alvl)/100
return 1
}
public fn_calcxp(const type, const arg1, const arg2, const arg3){
switch(type){
//CXT_KILL - arg1: attacker, arg2: victim
case CXT_KILL: return 100*lvl_diff_mod(arg1, arg2)
//CXT_DMG - arg1: attacker, arg2: victim, arg3: dmg_amount
case CXT_DMG: return arg3*lvl_diff_mod(arg1, arg2)
}
return 0
}
public fn_addxp(id, xp){ //adds xp to player id and calculates lvl
static temp_xp, next_lvl_xp
if(is_user_bot(id) && g_bot_savedata == 0)
return
if(g_p_level[id] > MAX_LVL)
return
if(get_user_flags(id) & ADMIN_RESERVATION)
temp_xp = floatround(xp*g_admin_xp_multipler)
else if(get_user_flags(id) & ADMIN_LEVEL_H)
temp_xp = floatround(xp*g_vip_xp_multipler)
else
temp_xp = floatround(xp*g_xp_multipler)
g_p_xp[id] += temp_xp
if(g_frequent_save == FREQ_S_INTERVAL)
g_p_temp_xp[id] += temp_xp
next_lvl_xp = g_p_level[id]*XP_INC+XP_START
temp_xp = (XP_START + next_lvl_xp)*(g_p_level[id]+1)/2
while(g_p_xp[id]>=temp_xp){
g_p_level[id]++
g_p_credits[id] += CREDITS_PER_LVL
next_lvl_xp += XP_INC
temp_xp += next_lvl_xp
}
g_p_progress[id] = 100-(temp_xp-g_p_xp[id])*100/next_lvl_xp
}
public plugin_end(){
data_save_all()
if(g_db_status == DB_READY && g_savedb == SAVEDB_MYSQL)
SQL_FreeHandle(g_sql_connection)
}
public handle_say(id){
static cache[32], arg1[32], arg2[32]
if(!g_user_control)
return PLUGIN_CONTINUE
read_args(cache, 31)
remove_quotes(cache)
strbreak(cache, arg1, 31, arg2, 31)
if(containi(arg1, "rpg")>-1 || containi(arg1, "menu")>-1){
menu_main(id)
}else if(containi(arg1, "help")>-1){
menu_help(id)
}else if(equali(arg1, "/deletexp")){
if(g_p_login_status[id] == REG_DONE){
data_delete(id, SAVEBY_LOGIN)
g_p_login_status[id] = REG_NONE
}else{
data_delete(id, g_saveby)
p_vars_reset(id)
data_load(id)
}
}
return PLUGIN_CONTINUE
}
public show_upgrades_info(id){
static temp[2048]
format(temp, 2048, "http://onlyonesuch.ru/rpg-spravka.html")
show_motd(id, temp, "[RPG mod] Upgrades Info")
return PLUGIN_HANDLED
}
public show_plugin_help(id){
static temp[2048]
format(temp, 2048, "http://onlyonesuch.ru/help.html")
show_motd(id, temp, "[RPG mod] Upgrades Info")
return PLUGIN_HANDLED
}
public show_credits(id){
static temp[2048]
format(temp, 2048, "http://onlyonesuch.ru/credits.html")
show_motd(id, temp, "[RPG mod] Upgrades Info")
return PLUGIN_HANDLED
}
//############## updated show_player_upgrades function:
public show_player_upgrades(id, target){
static temp[2048]
new pos, name[32]
pos += format(temp[pos], 2048-pos, "<html><meta charset=UTF-8><body style=^"background-color:#000000;color:#33EE33;font-size:15px;font-family:verdana;^">")
get_user_name(target, name, sizeof(name)-1)
pos += format(temp[pos], 2048-pos, "<p>Player: %s<br />Level: %d</p>", name, g_p_level[target])
pos += format(temp[pos], 2048-pos, "<table border=^"1^"><tr><th>Улучшения</th><th>Level</th>")
for(new i=0; i<MAX_UPGS; i++){
if(g_p_upg[target][i] <= 0)
continue
pos += format(temp[pos], 2048-pos, "</tr><tr><td>%s</td><td>%d</td>", g_upg_name[i], g_p_upg[target][i])
}
pos += format(temp[pos], 2048-pos, "</tr></table></body></html>")
show_motd(id, temp, "[RPG mod] Player upgrades")
return PLUGIN_HANDLED
}
public show_levels(id){
static temp[2048], players[32], num, i, j, x, pos
get_players(players, num)
for(i=1; i<num; i++){ //sort players
j = i-1
x = players[i]
while(j>-1 && g_p_level[players[j]]<g_p_level[x]){
players[j+1] = players[j]
j--
}
players[j+1] = x
}
pos = 0
pos += format(temp[pos], 2048-pos, "<html><body style=^"background-color:#000000;color:#33EE33;font-size:15px;font-family:verdana;^">")
pos += format(temp[pos], 2048-pos, "<table border=^"1^"><tr><th>Player Name</th><th>Level</th>")
for(i=0; i<num; i++){
pos += format(temp[pos], 2048-pos, "</tr><tr><td>%s</td><td>%d</td>", g_p_name[players[i]], g_p_level[players[i]])
}
pos += format(temp[pos], 2048-pos, "</tr></table></body></html>")
show_motd(id, temp, "[RPG mod] Player levels")
return PLUGIN_HANDLED
}
public menu_help(id){
static pos, cache[512]
pos = 0
new keys = (1<<0)|(1<<1)|(1<<2)|(1<<9)
pos += formatex(cache[pos], 511-pos, "\yRPG mod \d[#.4]\wПомощь^n")
pos += formatex(cache[pos], 511-pos, "1. Информация о улучшениях^n")
pos += formatex(cache[pos], 511-pos, "2. Важная информация^n")
pos += formatex(cache[pos], 511-pos, "3. Создатели^n")
pos += formatex(cache[pos], 511-pos, "^n0. Назад^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_help(id,key){
switch (key){
case 0: {show_upgrades_info(id); menu_help(id);}
case 1: {show_plugin_help(id); menu_help(id);}
case 2: {show_credits(id); menu_help(id);}
case 9: menu_main(id)
default: return PLUGIN_HANDLED
}
return PLUGIN_HANDLED
}
public get_rpg_settings(id){
static tmp[32], i
if(is_user_bot(id))
return
get_user_info(id, "_rpgm_cfg", tmp, 31)
if(strlen(tmp) < MAX_SETTINGS){
client_cmd(id, "setinfo _rpgm_cfg %s", g_settings_default)
log_amx("missing settings for %d", id)
copy(tmp, 31, g_settings_default)
}
for(i=0; i<MAX_SETTINGS; i++){
if(tmp[i] >= '0' && tmp[i] <= '9')
g_p_settings[id][i] = tmp[i]-'0'
else
g_p_settings[id][i] = 0
if(g_p_settings[id][i] > g_settings_maxval[i])
g_p_settings[id][i] = g_settings_maxval[i]
}
}
public set_rpg_settings(id){
static i, pos, cache[32]
if(is_user_bot(id))
return
pos = 0
for(i=0; i<MAX_SETTINGS; i++)
pos += formatex(cache[pos], 32-pos, "%d", g_p_settings[id][i])
client_cmd(id, "setinfo _rpgm_cfg %s", cache)
}
public menu_settings(id){
static pos, cache[512]
pos = 0
new keys = (1<<0)|(1<<1)|(1<<2)|(1<<9)
pos += formatex(cache[pos], 511-pos, "\yRPG mod \d[#.5]\wНастройки^n")
pos += formatex(cache[pos], 511-pos, "1. Показывать \yМеню\w после смерти [%s\w]^n", g_p_settings[id][0]?"\yВКЛ":"\rВЫКЛ")
pos += formatex(cache[pos], 511-pos, "2. Показывать \yинформацию\w (lvl, кредиты) в чате [%s\w]^n", g_p_settings[id][1]?"\yВКЛ":"\rВЫКЛ")
pos += formatex(cache[pos], 511-pos, "3. hud_centerid 0^n")
pos += formatex(cache[pos], 511-pos, "//нажми 3 если \yинформация\w отображается по середине экрана^n")
pos += formatex(cache[pos], 511-pos, "//, чтобы переместить её в чате^n")
pos += formatex(cache[pos], 511-pos, "^n0. Назад^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_settings(id,key){
if(key==9){
menu_main(id)
return PLUGIN_HANDLED
}
if(key==2){
client_cmd(id, "hud_centerid 0")
menu_settings(id)
return PLUGIN_HANDLED
}
g_p_settings[id][key] = !g_p_settings[id][key]
set_rpg_settings(id)
menu_settings(id)
return PLUGIN_HANDLED
}
public menu_data(id){
static pos, cache[512]
pos = 0
new keys = (1<<9)
pos += formatex(cache[pos], 511-pos, "\yRPG mod \d[#.6]\wО сохранениях^n")
if(g_db_status!=DB_READY){
pos += formatex(cache[pos], 511-pos, "База данных не подключена^n")
pos += formatex(cache[pos], 511-pos, "Xp, улучшения и кредиты \yне\w сохраняются^n")
pos += formatex(cache[pos], 511-pos, "^n0. Назад^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
keys = keys|(1<<0)
pos += formatex(cache[pos], 511-pos, "База данных подключена.^n")
pos += formatex(cache[pos], 511-pos, "Xp, улучшения и кредиты \yсохраняются\w автоматически^n")
if(g_frequent_save==1)
pos += formatex(cache[pos], 511-pos, "каждый раунд или ")
pos += formatex(cache[pos], 511-pos, "при отключении")
if(g_frequent_save==2)
pos += formatex(cache[pos], 511-pos, " or gain much xp")
if(g_p_login_status[id] == REG_DONE){
pos += formatex(cache[pos], 511-pos, ".^nВаши данные сохраняются по \yLOGIN\w.^n")
pos += formatex(cache[pos], 511-pos, "^n\wВы вошли в систему^n")
pos += formatex(cache[pos], 511-pos, "\wЛогин: \y%s^n", g_p_username[id])
pos += formatex(cache[pos], 511-pos, "\wПароль: %s%s^n", g_p_pw_hidden[id] ? "\d" : "\y", g_p_pw_hidden[id] ? "(скрытый)" : g_p_password[id])
pos += formatex(cache[pos], 511-pos, "\w1. %s пароль^n", g_p_pw_hidden[id] ? "показать":"скрыть")
pos += formatex(cache[pos], 511-pos, "^n0. Назад^n")
}else{
pos += formatex(cache[pos], 511-pos, ".^nВаши данные сохраняются по ")
switch(g_saveby){
case SAVEBY_STEAMID: pos += formatex(cache[pos], 511-pos, "\ySTEAMID\w.^n")
case SAVEBY_IP: pos += formatex(cache[pos], 511-pos, "\yIP\w.^n")
case SAVEBY_NAME: pos += formatex(cache[pos], 511-pos, "\yNAME\w.^n")
}
pos += formatex(cache[pos], 511-pos, "Вы не авторизованы^n")
pos += formatex(cache[pos], 511-pos, "1. Помощь^n")
pos += formatex(cache[pos], 511-pos, "(содержит информацию о сохранениях)^n")
pos += formatex(cache[pos], 511-pos, "^n0. Назад^n")
}
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_data(id,key){
if(key==9){
menu_main(id)
return PLUGIN_HANDLED
}
if(g_p_login_status[id] == REG_DONE){
g_p_pw_hidden[id] = !g_p_pw_hidden[id]
}else{
show_plugin_help(id)
}
menu_data(id)
return PLUGIN_HANDLED
}
public menu_main(id){
static pos, cache[512]
if(!g_user_control)
return PLUGIN_HANDLED
pos = 0
new keys = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<9)
pos += formatex(cache[pos], 511-pos, "\yRPG mod \d[#]\wМеню^n")
if(g_in_team==1)
pos += formatex(cache[pos], 511-pos, "Upgrades work only for \yTerrorists\w^n")
else if(g_in_team==2)
pos += formatex(cache[pos], 511-pos, "Upgrades work only for \yCT\w^n")
pos += formatex(cache[pos], 511-pos, "1. Купить улучшение^n")
pos += formatex(cache[pos], 511-pos, "2. Продать улучшение^n")
pos += formatex(cache[pos], 511-pos, "3. Прокачка игроков^n")
pos += formatex(cache[pos], 511-pos, "4. Мои улучшения^n")
pos += formatex(cache[pos], 511-pos, "5. Помощь^n")
pos += formatex(cache[pos], 511-pos, "6. Настройки^n")
pos += formatex(cache[pos], 511-pos, "7. О сохранениях^n")
pos += formatex(cache[pos], 511-pos, "^n0. Выход^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_main(id,key){
static i
switch (key){
case 0: menu_buy_upg(id, 0)
case 1: {
g_p_sm_upg_cnt[id] = 0
for(i=0; i<MAX_UPGS; i++){
if(g_p_upg[id][i]){
g_p_sm_upg[id][g_p_sm_upg_cnt[id]] = i
g_p_sm_upg_cnt[id]++
}
}
menu_sell_upg(id, 0)
}
case 2: menu_show_levels(id, 0)
case 3: {show_player_upgrades(id,id); menu_main(id);}
case 4: menu_help(id)
case 5: menu_settings(id)
case 6: menu_data(id)
default: return PLUGIN_HANDLED
}
return PLUGIN_HANDLED
}
public menu_buy_upg(id, page){
static i, keys, pos, upg, price, max, cache[1024]
pos = 0
keys = 0
if(page*8>=g_enabled_upgs)
page = 0
g_p_menu_page[id] = page
max = (g_enabled_upgs-1)/7+1
if(max<1)
max=1
pos += format(cache[pos], 1023-pos, "\yRPG mod \d[#.1]\wПокупка улучшений^n\d[%d/%d]\w[Кредиты: \y%d\w]^n\wn. \d[ \wlvl\d ][\wцена\d]\wулучшение^n^n", page+1, max, g_p_credits[id])
max = g_enabled_upgs - page*7
if(max>8)
max=8
for(i=0; i<7; i++){
if(i>=max){
pos += formatex(cache[pos], 1023-pos, "\d%d.^n", i+1)
continue
}
upg = g_enabled_list[i+page*7]
price = g_upg_sp[upg] + g_upg_ip[upg]*g_p_upg[id][upg]
if(g_p_upg[id][upg] >= g_upg_maxlvl[upg]){
pos += formatex(cache[pos], 1023-pos, "\d%d. [\rmax\d][-----]%s^n", i+1, g_upg_name[upg])
}else if(price > g_p_credits[id]){
pos += formatex(cache[pos], 1023-pos, "\d%d. [%4d ][\r%5d \d]%s^n", i+1, g_p_upg[id][upg]+1, price, g_upg_name[upg])
}else{
pos += formatex(cache[pos], 1023-pos, "\w%d. \d[\w%4d \d][\y%5d \d]\w%s^n", i+1, g_p_upg[id][upg]+1, price, g_upg_name[upg])
keys = keys|(1<<i)
}
}
pos += formatex(cache[pos], 1023-pos, "^n%s9. Больше...^n", g_enabled_upgs>8 ? "\w" : "\d")
keys = keys|(1<<8)|(1<<9)
pos += formatex(cache[pos], 1023-pos, "\w0. Назад^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_buy_upg(id,key){
static upg
if(key<7){
upg = g_enabled_list[g_p_menu_page[id]*7+key]
g_p_credits[id] -= g_upg_sp[upg] + g_upg_ip[upg]*g_p_upg[id][upg]
g_p_upg[id][upg]++
upgrade_change(id, upg)
menu_buy_upg(id, g_p_menu_page[id])
}else if(key==8){
menu_buy_upg(id, g_p_menu_page[id]+1)
}else{
menu_main(id)
}
return PLUGIN_HANDLED
}
public menu_sell_upg(id, page){
static i, keys, pos, upg, value, max, cache[1024]
pos = 0
keys = 0
if(page*8>=g_p_sm_upg_cnt[id])
page = 0
g_p_menu_page[id] = page
max = (g_p_sm_upg_cnt[id]-1)/7+1
if(max<1)
max=1
pos += format(cache[pos], 1023-pos, "\yRPG mod \d[#.2]\wПродажа улучшений^n\d[%d/%d]\w[Кредиты: \y%d\w]^n\wn. \d[ \wlvl\d ][\wцена\d]\wулучшение^n^n", page+1, max, g_p_credits[id])
max = g_p_sm_upg_cnt[id] - page*7
if(max>8)
max=8
for(i=0; i<7; i++){
if(i>=max){
pos += formatex(cache[pos], 1023-pos, "\d%d.^n", i+1)
continue
}
upg = g_p_sm_upg[id][i+page*7]
value = g_upg_sp[upg] + g_upg_ip[upg]*(g_p_upg[id][upg]-1)
if(g_upg_enabled[upg])
value = value*3/4
if(g_p_upg[id][upg] <= 0){
pos += formatex(cache[pos], 1023-pos, "\d%d. [ \r0 \d][ \r0 \d]%s^n", i+1, g_upg_name[upg])
}else{
pos += formatex(cache[pos], 1023-pos, "\w%d. \d[\w%4d \d][\y%5d \d]\w%s^n", i+1, g_p_upg[id][upg], value, g_upg_name[upg])
keys = keys|(1<<i)
}
}
pos += formatex(cache[pos], 1023-pos, "^n%s9. Больше...^n", g_p_sm_upg_cnt[id]>8 ? "\w" : "\d")
keys = keys|(1<<8)|(1<<9)
pos += formatex(cache[pos], 1023-pos, "\w0. Назад^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_sell_upg(id,key){
static upg, value
if(key<8){
upg = g_p_sm_upg[id][g_p_menu_page[id]*7+key]
value = g_upg_sp[upg] + g_upg_ip[upg]*(g_p_upg[id][upg]-1)
if(g_upg_enabled[upg])
value = value*3/4
g_p_credits[id] += value
g_p_upg[id][upg]--
upgrade_change(id, upg)
menu_sell_upg(id, g_p_menu_page[id])
}else if(key==8){
menu_sell_upg(id, g_p_menu_page[id]+1)
}else{
menu_main(id)
}
return PLUGIN_HANDLED
}
public upgrade_change(id, upg){
static health, temp
switch(upg){
case UPG_HEALTH:{
temp = 100 + g_p_upg[id][UPG_HEALTH]*25
temp -= g_p_maxhealth[id]
g_p_maxhealth[id] += temp
if(!is_user_alive(id) || temp <= 0)
return
if(g_in_team && g_in_team != g_p_team[id])
return
health = get_user_health(id)
if(health >= g_p_maxhealth[id])
return
health += temp
if(health >= g_p_maxhealth[id])
set_user_health(id, g_p_maxhealth[id])
else
set_user_health(id, health)
}
case UPG_STEALTH:{
if(!is_user_alive(id))
return
if(g_in_team && g_in_team != g_p_team[id])
return
temp = 255-40*g_p_upg[id][UPG_STEALTH]
if(temp<0)
temp=0
set_user_rendering(id, 0, 0, 0, 0, kRenderTransAlpha, temp)
}
}
}
//############## new functions and global variable:
new g_p_sp_menu[MAX_PLAYERS+1][8]
public menu_show_levels(id, page){
static cache[1024], players[32], num, i, j, x, pos, keys, max, name[32], tmp_id
get_players(players, num)
for(i=1; i<num; i++){ //sort players
j = i-1
x = players[i]
while(j>-1 && g_p_level[players[j]]<g_p_level[x]){
players[j+1] = players[j]
j--
}
players[j+1] = x
}
pos = 0
keys = 0
if(page*8>=num)
page = 0
g_p_menu_page[id] = page
max = (num-1)/8+1
if(max<1)
max=1
pos += format(cache[pos], 1023-pos, "\yRPG mod \d[#.3] [%d/%d]\w Player levels^n^n", page+1, max)
max = num - page*8
if(max>8)
max=8
for(i=0; i<8; i++){
if(i>=max){
pos += formatex(cache[pos], 1023-pos, "\d%d.^n", i+1)
continue
}
tmp_id = players[i+page*8]
g_p_sp_menu[id][i] = tmp_id
get_user_name(tmp_id, name, sizeof(name)-1)
pos += formatex(cache[pos], 1023-pos, "\w%d. \d[\y%4d \d]\w %s^n", i+1, g_p_level[tmp_id], name)
keys = keys|(1<<i)
}
pos += formatex(cache[pos], 1023-pos, "^n%s9. More...^n", num>8 ? "\w" : "\d")
keys = keys|(1<<8)|(1<<9)
pos += formatex(cache[pos], 1023-pos, "\w0. Back^n")
show_menu( id, keys, cache, -1)
return PLUGIN_HANDLED
}
public hnd_menu_show_levels(id,key){
if(key<8){
if(is_user_connected(g_p_sp_menu[id][key]))
show_player_upgrades(id, g_p_sp_menu[id][key])
else
client_print(id, print_chat, "[RPG mod] Player disconnected")
menu_show_levels(id, g_p_menu_page[id])
}else if(key==8){
menu_show_levels(id, g_p_menu_page[id]+1)
}else{
menu_main(id)
}
return PLUGIN_HANDLED
}