ReHLDS/HLDS Micro Army Rank System

oqde

Пользователь
Регистрация
20 Окт 2017
Сообщения
47
Симпатии
14
#62
относительно рангов, всё прекрасно и работоспособно ещё с 1.27Hz.
Скиллы тоже работают, c модуля csx точно, и в 1.29Hz, в csx даже буква из Elo Method верно отображает (там не более 100% тогда как в Elo методе до 210%). благодаря тому что csstats sql округляет результат, в mars он будет чуток отличаться (mars точнее)... сейчас решаем эту загвоздку.
релиз 1.29Hz с исправлением всех известных мне багов выйдет завтра.
 

ade888

Пользователь
Регистрация
9 Июн 2017
Сообщения
184
Симпатии
24
Пол
Мужской
#63
oqde, званий можно будет добавлять без ограничений или что ?
 

oqde

Пользователь
Регистрация
20 Окт 2017
Сообщения
47
Симпатии
14
#64
oqde, званий можно будет добавлять без ограничений или что ?
их и так можно добавлять по желанию, ещё с самого первого релиза.
полный список изменений будет в шапке.
 

Izmayl7

Пользователь
Регистрация
9 Июн 2017
Сообщения
477
Симпатии
87
Пол
Мужской
#66
скриншоты добавьте)) да и бонусы за достижения определенного звания есть или нет(там денежный бонус за достижения определенного звания)?! заранее спасибо за ответ=!)
 

Izmayl7

Пользователь
Регистрация
9 Июн 2017
Сообщения
477
Симпатии
87
Пол
Мужской
#68
т.е. анеш бонус что ли? я имел ввиду за звания, был ты рядовой достиг там допустим лейтенанта и т.д. и тебе за это достижения звания, как ты его достиг, ввиде бонуса деньга еще выдалась)) как то так))):confused::)
 

Феня

Пользователь
Регистрация
11 Июл 2017
Сообщения
70
Симпатии
7
#69
доброго времени суток,последний скомпиленный марс 1.29 от души скиньте пожалуйста,буду очень признателен!
 

ade888

Пользователь
Регистрация
9 Июн 2017
Сообщения
184
Симпатии
24
Пол
Мужской
#72
с чем звязанно данная ошибка

Код:
L 11/14/2017 - 17:49:03: [AMXX] To enable debug mode, add "debug" after the plugin name in plugins.ini (without quotes).
L 11/14/2017 - 17:49:05: [AMXX] Run time error 4 (plugin "MARS_1.29Hz.amxx") - debug not enabled!
Код:
L 11/14/2017 - 17:52:19: Function is not present (function "") (plugin "MARS_1.29Hz.amxx")
L 11/14/2017 - 17:52:19: [AMXX] Run time error 10 (plugin "MARS_1.29Hz.amxx") (native "set_task") - debug not enabled!
 

oqde

Пользователь
Регистрация
20 Окт 2017
Сообщения
47
Симпатии
14
#73
с чем звязанно данная ошибка

Код:
L 11/14/2017 - 17:49:03: [AMXX] To enable debug mode, add "debug" after the plugin name in plugins.ini (without quotes).
L 11/14/2017 - 17:49:05: [AMXX] Run time error 4 (plugin "MARS_1.29Hz.amxx") - debug not enabled!
Код:
L 11/14/2017 - 17:52:19: Function is not present (function "") (plugin "MARS_1.29Hz.amxx")
L 11/14/2017 - 17:52:19: [AMXX] Run time error 10 (plugin "MARS_1.29Hz.amxx") (native "set_task") - debug not enabled!
возможно HUD_REPEAT_TIME имеет целый тип данных. например 2 заместо 2.0
включите debug mode, добавив
MARS_1.29Hz.amxx debug
в plugins.ini
 

ade888

Пользователь
Регистрация
9 Июн 2017
Сообщения
184
Симпатии
24
Пол
Мужской
#74
oqde, Понял проблему.... Проблема заключаеться в том что когда игрок даходит до маскимального уровня начинает в консоле выходит ошибки и у всех игроков пропадают звания

/**
* Micro Army Rank System by Ge3eR
* 13.11.2017
* v1.29Hz
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <csx> // По умолчанию включает и <csstats>. не трогать.
#if AMXX_VERSION_NUM < 183
#include <colorchat> // colorchat.inc от aghl.ru
#define MAX_NAME_LENGTH 32
#endif

/* Раскомментируйте, для частичной поддержки AES нативов и форвардов */
//#define AES_PLUGINS_COMPATIBLE

/* Раскомментируйте, если хотите дополнить HUD инфой о скилле */
#define WITH_SKILLS

/* -- READ_STATS
* Откуда будем считывать статистику?
* 0 - CSX or CSX Extended (Module)
* 1 - CSSTATS MYSQL by SKAJIbnEJIb // автором не тестировалось, но говорят норм )
* 2 - CSSTATSX SQL by serfreeman1337 + CSX_DUMMY Module// учтите, что CSSTATSX SQL должен быть в режиме csstats_sql_forwards 1
*/
#define READ_STATS 2

// Настройки отображения HUD информера
#define HUD_LIVE_COLOR_R 0
#define HUD_LIVE_COLOR_G 128
#define HUD_LIVE_COLOR_B 0
#define HUD_LIVE_AXIS_X 0.01
#define HUD_LIVE_AXIS_Y 0.22

#define HUD_SPEC_COLOR_R 28
#define HUD_SPEC_COLOR_G 90
#define HUD_SPEC_COLOR_B 28
#define HUD_SPEC_AXIS_X 0.01
#define HUD_SPEC_AXIS_Y 0.15

// Промежуток между сообщениями информера
#define HUD_REPEAT_TIME 1.5

/* -- LEVELUP_CONGRATULATION
* Оповещение о повышении уровня
* 0 - отключено
* 1 - включено (оповещает в чат, HUD и звуком)
*/
#define LEVELUP_CONGRATULATION 1

#if LEVELUP_CONGRATULATION == 1
// Настройки отображения HUD сообщения о повышении уровня
#define HUD_LEVELUP_COLOR_R 0
#define HUD_LEVELUP_COLOR_G 128
#define HUD_LEVELUP_COLOR_B 0
#define HUD_LEVELUP_AXIS_X -1.0
#define HUD_LEVELUP_AXIS_Y 0.15
#endif

#define ONSTART_WAIT_TIME /* CS */ 1.6 // задержка перед чтением статистики. (увеличить при плохом соединении с БД)

// автограф
#define PLAGIN "Micro Army Rank System"
#define VERSIA "1.29Hz"
#define AUTHOR "Ge3eR"

// остальное, системное
#if READ_STATS == 1
#include <csstats_mysql>
; // again ...
#endif
#if READ_STATS == 2
#include <csstatsx_sql> // и кто же это у нас пишет либы без semicolon?
; // hot fix by wopox1337
#endif

#if defined AES_PLUGINS_COMPATIBLE
new level_up_forward, dummy;
new client_bonus[33];
#endif

#pragma semicolon 1

#define STATS_KILLS 0
#define STATS_DEATHS 1
/*
#define STATS_HEADSHOTS 2
#define STATS_DAMAGE 6
*/
/* -- EXP_MODE .. будет в следующем релизе )
* Режим чтения опыта
* 0 - считать за опыт фраги (kills)
* 1 - считать за опыт хедшоты (headshots)
* 2 - считать за опыт общий урон (damage)
#define EXP_MODE 0
*/
#define MAX_RANGS sizeof mars_exp
#define IsEntPlayer(%1) (1<=%1<=g_maxplayers)

/* input: level
* output: next exp border
*///level_reqexp
#define level_reqexp(%1) mars_exp[min( (%1 + 1), min(array_size-1, MAX_RANGS) )]

#define LEVEL_NAME_LENGHT 64 // если ранг длинный и обрезается, изменить.

#define MARS_ST_EXP 0
#define MARS_ST_LEVEL 1
#define MARS_ST_NEXTEXP 2
#define MARS_ST_END_DIGIT 3

// ну вы поняли
new const prefix[] = "MARS";

#if defined WITH_SKILLS
new const skill_letters[][] =
{
"L-", "L", "L+", "M-", "M", "M+", "H-",
"H", "H+", "P-", "P", "P+", "G"
};
#endif

// Глобальные
new g_maxplayers;
new Array:rang_list;
new informer_sync_obj;
new array_size;

// оптимизируем запросы к стате засчитывая в оффлайн режиме)
new client_kills[33];
new client_kills_req[33];
new client_level[33];

#if defined WITH_SKILLS
#if READ_STATS == 0 || READ_STATS == 1
new client_deaths[33];
#endif
new Float:client_skill[33] = { 100.0, ... };
#endif

// Так быстрее вычислять ранг игрока. изменить по желанию.
new mars_exp[] = { // при добавлении последней записи, следите чтобы после неё небыло запятой
00000, 00002, 00005, 00010, 00015
}; // and so on, to infinity...

public plugin_init()
{
register_plugin(PLAGIN, VERSIA, AUTHOR);

rang_list = ArrayCreate(LEVEL_NAME_LENGHT);
informer_sync_obj = CreateHudSyncObj();
g_maxplayers = get_maxplayers();

register_srvcmd("mars_reload_list", "_mars_reload_list"); // Hot reload rank list
register_srvcmd("mars_reload_stats", "_mars_reload_stats"); // Hard reloading stats, for connected players

register_cvar("mars", VERSIA, FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED);

#if defined AES_PLUGINS_COMPATIBLE
level_up_forward = CreateMultiForward("aes_player_levelup",ET_IGNORE,FP_CELL,FP_CELL,FP_CELL);

if(get_cvar_pointer("aes_track_mode") == 0) register_cvar("aes_track_mode","0"); // "-1" ?
#endif

register_dictionary("mars.txt");

set_task(HUD_REPEAT_TIME, "informer", .flags="b");
}

public plugin_cfg()
{
server_print("[%s] Loaded %d Ranks", prefix, ( array_size = load_rangs() ) );
}

public _mars_reload_list()
{
ArrayClear(rang_list);
server_print("[%s] ReLoaded with %d Ranks", prefix, ( array_size = load_rangs() ) );

// пересчёт уровня. это понадобится, если новых уровней меньше чем было раньше // 1.28 bug fix
for(new id = 1; id <= g_maxplayers; id++)
if(is_user_connected(id))
client_level[id] = get_level_index(client_kills[id]);
}

load_rangs()
{
new file;
new lang[3];
new path[256], cfg_path[128];

get_configsdir(cfg_path,charsmax(cfg_path));
get_cvar_string("amx_language", lang, charsmax(lang));

format(path, charsmax(path), "%s/mars_lists/mars_list_%s.ini", cfg_path, lang);

if( !(file = fopen(path, "rt")))
{
format(path, charsmax(path), "%s/mars_list.ini", cfg_path);
file = fopen(path, "rt");
}

if(file)
{
new message[LEVEL_NAME_LENGHT];

while(!feof(file))
{
fgets(file, message, charsmax(message));
trim(message);
if(strlen(message) && message[0] != ';')
ArrayPushString(rang_list, message);
}
fclose(file);

new size = ArraySize(rang_list);
if(!size)
{
server_print("[%s] file^"%s^" is empty! Loaded 1 fake rank.", prefix, path);
ArrayPushString(rang_list, "Марсианин");

return 1;
}
return size;
}

server_print("[%s] File ^"%s^" not found! Loaded 1 fake rank.", prefix, path);
ArrayPushString(rang_list, "Марсианин");

return 1;
}

public informer()
{
static watching;
static stats[MARS_ST_END_DIGIT];
static level_name[LEVEL_NAME_LENGHT];
static output[96+ LEVEL_NAME_LENGHT];
static id;

#if defined WITH_SKILLS
static Float:skill;
#endif

for(id = 1; id <= g_maxplayers; id++)
{
if(!is_user_connected(id) || is_user_bot(id)) continue;

//entity_get_int(id, EV_INT_iuser2); // maybe engine?
watching = pev(id, pev_iuser2);

if(is_user_alive(watching) && !is_user_alive(id))
{
get_player_stats(watching, stats);

#if defined WITH_SKILLS
skill = _get_skill(watching);
#endif
}
else
{
get_player_stats(id, stats);

#if defined WITH_SKILLS
skill = _get_skill(id);
#endif
}

ArrayGetString(rang_list, stats[MARS_ST_LEVEL], level_name, charsmax(level_name));

#if defined WITH_SKILLS
format(output, charsmax(output), "%L^n%L^n%L"
, LANG_SERVER, "MARS_HUD_RANK"
, level_name

, LANG_SERVER, "MARS_HUD_EXP"
, stats[MARS_ST_EXP], max(stats[MARS_ST_EXP], stats[MARS_ST_NEXTEXP]) //Предела нет!

, LANG_SERVER, "MARS_HUD_SKILL"
, skill_letters[skill_id(
skill
)], skill
);
#else
format(output, charsmax(output), "%L^n%L"
, LANG_SERVER, "MARS_HUD_RANK"
, level_name

, LANG_SERVER, "MARS_HUD_EXP"
, stats[MARS_ST_EXP], max(stats[MARS_ST_EXP], stats[MARS_ST_NEXTEXP]) //Предела нет!
);
#endif

ClearSyncHud(id,informer_sync_obj);

if(is_user_alive(id))
{
set_hudmessage(HUD_LIVE_COLOR_R, HUD_LIVE_COLOR_G, HUD_LIVE_COLOR_B, HUD_LIVE_AXIS_X, HUD_LIVE_AXIS_Y, 0
, .holdtime = HUD_REPEAT_TIME, .channel = 3
, .fxtime=0.0, .fadeintime=0.1, .fadeouttime=0.1
);
}
else
{
set_hudmessage(HUD_SPEC_COLOR_R, HUD_SPEC_COLOR_G, HUD_SPEC_COLOR_B, HUD_SPEC_AXIS_X, HUD_SPEC_AXIS_Y, 0
, .holdtime = HUD_REPEAT_TIME, .channel = 3
, .fxtime=0.0, .fadeintime=0.1, .fadeouttime=0.1
);
}

ShowSyncHudMsg(id, informer_sync_obj, output);
}
}

get_player_stats(id, stats[])
{
stats[MARS_ST_EXP] = client_kills[id];
stats[MARS_ST_LEVEL] = client_level[id];
stats[MARS_ST_NEXTEXP] = level_reqexp(client_level[id]);
}

get_level_index(exp)
{
new index = 0;
for(new i = 0; i < array_size && i < MAX_RANGS; i++) // it works!
{
if(mars_exp <= exp)
index = i;
}
return index;
}

stock Float:_get_skill(id)
{
#if READ_STATS == 2
return client_skill[id];
#else
return effec(client_kills[id], client_deaths[id]);
#endif
}

stock Float:effec(kills, deaths) return (100.0 * float(kills) / float(kills + deaths));

stock skill_id(Float:skill)
{
#if READ_STATS == 2
switch(floatround(skill))
{
case 0..59: return 0; case 60..74: return 1; case 75..84: return 2; // L
case 85..99: return 3; case 100..114: return 4; case 115..129: return 5; // M
case 130..139: return 6; case 140..149: return 7; case 150..164: return 8; // H
case 165..179: return 9; case 180..194: return 10; case 195..209: return 11;// P
case 210..999: return 12; // G
}
#else // будет нормально отображать букву для простых смертных с READ_STATS 0
switch(floatround(skill))
{
case 0..14: return 0; case 15..29: return 1; case 30..44: return 2; // L
case 45..51: return 3; case 52..63: return 4; case 64..69: return 5; // M
case 70..74: return 6; case 75..79: return 7; case 80..85: return 8; // H
case 86..89: return 9; case 90..94: return 10; case 95..97: return 11;// P
case 98..100: return 12; // G
}
#endif
return 0;
}

public client_death(killer,victim)
{
if(!(IsEntPlayer(killer)) || !(IsEntPlayer(victim))
|| killer == victim
) return;

// зачтём
client_kills[killer]++;

#if defined WITH_SKILLS // немного больше вычислений...

#if READ_STATS == 0 || READ_STATS == 1
client_deaths[victim]++;
#endif

#if READ_STATS == 2 // The ELO Method

static Float:delta; delta = 1.0 / (1.0 + floatpower(10.0,(client_skill[killer] - client_skill[victim]) / 100.0));
static Float:koeff; koeff = 0.0;

if(client_kills[killer] < 100) koeff = 2.0; else koeff = 1.5;

client_skill[killer] += (koeff * delta);
client_skill[victim] -= (koeff * delta);

// log_amx("[MARS %d] %f (Client k)", killer, client_skill[killer]);
// log_amx("[MARS %d] %f (Client v)", victim, client_skill[victim]);

#endif

#endif

if(--client_kills_req[killer]) return; // пропускаем, пока игрок не достигнет нового уровня

// учтём
if(client_level[killer]< MAX_RANGS && client_level[killer]< array_size) client_level[killer]++;

client_kills_req[killer] = level_reqexp(client_level[killer])-client_kills[killer]; // 1.27 bug fixed

#if defined AES_PLUGINS_COMPATIBLE
// set event levelup
ExecuteForward(level_up_forward, dummy, killer, client_level[killer], client_level[killer] - 1);
#endif

// покажем
#if LEVELUP_CONGRATULATION == 1
static local_client_name[MAX_NAME_LENGTH];
static local_level_name[LEVEL_NAME_LENGHT];

get_user_name(killer, local_client_name,charsmax(local_client_name));
ArrayGetString(rang_list, client_level[killer], local_level_name, charsmax(local_level_name));

set_hudmessage(HUD_LEVELUP_COLOR_R, HUD_LEVELUP_COLOR_G, HUD_LEVELUP_COLOR_B, HUD_LEVELUP_AXIS_X, HUD_LEVELUP_AXIS_Y, 0,.holdtime = 8.0);
show_hudmessage(0, "%L", LANG_SERVER, "MARS_HUD_CONGRATULATION", local_client_name, local_level_name);

client_print_color(0, print_team_default
, "^4[^1%s^4] %L", prefix, LANG_SERVER, "MARS_TXT_CONGRATULATION", local_client_name, local_level_name);

client_cmd(0, "spk gonarch/gon_step1.wav");
#endif
}

public client_putinserver(id)
{
// немного подождём, а вдруг ещё не загрузилась инфа?
set_task(ONSTART_WAIT_TIME, "onstart_set_exp", id + 129);
}

public onstart_set_exp(index)
{
new id = index - 129;

if(!is_user_connected(id)) return;

// обнуляем
client_kills[id] = 0;

#if defined WITH_SKILLS
#if READ_STATS != 2
client_deaths[id] = 0;
#endif
client_skill[id] = 100.0;
#endif

#if defined AES_PLUGINS_COMPATIBLE
client_bonus[id] = 0;
#endif
// и считываем
_read_stats(id);
}

_read_stats(id)
{
#if READ_STATS == 0
static stats[8];
static bh[8];

if(!get_user_stats(id,stats,bh))
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif
#if READ_STATS == 1
static stats[22];

if(csstats_get_user_stats(id, stats) <= 0)
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif
#if READ_STATS == 2
static stats[8];
static bh[8];

if(!get_user_stats_sql(id,stats,bh))
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif

// оптимизируем подсчёт уровня
client_level[id] = get_level_index(client_kills[id]);
client_kills_req[id] = level_reqexp(get_level_index(client_kills[id]))-client_kills[id];

#if defined WITH_SKILLS

#if READ_STATS == 0 || READ_STATS == 1
client_deaths[id] = stats[STATS_DEATHS];
client_skill[id] = (100.0 * float(stats[STATS_KILLS]) / float(stats[STATS_KILLS] + stats[STATS_DEATHS]));
#endif

#if READ_STATS == 2
if(!get_user_skill(id,client_skill[id]))
client_skill[id] = 100.0;
if(!client_skill[id]) client_skill[id] = 100.0;
#endif
// log_amx("[MARS %d] %f (FirstRead)", id, client_skill[id]);
#endif
}
/*
#if AMXX_VERSION_NUM < 183
#define client_disconnected client_disconnect
#endif
public client_disconnected(id)
{
log_amx("[MARS %d] %f (Disconnect)", id, client_skill[id]);
}
*/

public _mars_reload_stats() /* постарайтесь не юзать эту функцию без надобности. Обновление статистики в модуле csx или других плагинах
не мгновенно, а зачастую настраивается на запись под конец карты или при дисконнекте. так что вы рискуете временно сбить счёт уже успевшим
его набить игрокам. */
{
for(new id = 1; id <= g_maxplayers; id++)
{
if(is_user_connected(id)) _read_stats(id);
}
server_print("stats reloaded");
}

// Проброс натив ... конец плагина )

public plugin_natives()
{
register_library("mars_main");

#if defined WITH_SKILLS
register_native("mars_get_skill", "_mars_get_skill", true); // get Real-Time skill
#endif

#if defined AES_PLUGINS_COMPATIBLE
register_library("mars_to_aes_main");

// Совместимость с плагинами использующими AES 0.5 Vega..
register_native("aes_get_player_level", "_mars_get_player_level", true);
register_native("aes_get_player_exp", "_mars_get_player_exp", true);
register_native("aes_get_player_reqexp", "_mars_get_player_reqexp", true);
register_native("aes_get_level_name", "_mars_get_level_name");
register_native("aes_get_level_reqexp", "_mars_get_level_reqexp", true);
register_native("aes_get_max_level", "_mars_get_max_level", true);
register_native("aes_get_exp_level", "_mars_get_exp_level", true);

// fake natives ?
register_native("aes_set_player_bonus", "_mars_set_player_bonus");
register_native("aes_get_player_bonus", "_mars_get_player_bonus", true);
register_native("aes_set_player_level", "_mars_set_player_level");
register_native("aes_set_player_exp", "_mars_set_player_exp");
// mega fake native :)
register_native("aes_find_stats_thread", "_mars_find_stats_thread"); // mega fake :D

// Совместимость с AES 0.4
register_native("aes_get_stats", "_mars_get_player_stats"); // do not use it anymore (in aes 0.5 Vega, will be return false)
register_native("aes_get_player_stats", "_mars_get_player_stats");
register_native("aes_get_exp_to_next_level","_mars_get_level_reqexp", true);
register_native("aes_get_level_for_exp", "_mars_get_exp_level", true);

// aes_cstrike_exp for AES: STATSX CSTRIKE plugin
register_native("aes_get_exp_for_stats_f","_mars_get_exp_for_stats_f");
register_native("aes_get_exp_for_stats","_mars_get_exp_for_stats");
#endif
}

#if defined WITH_SKILLS
public Float:_mars_get_skill(id)
{
if ( !IsEntPlayer(id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", id);
return -1.0;
}
return _get_skill(id);
}
#endif

#if defined AES_PLUGINS_COMPATIBLE
// Returns required experience to pass level
// @lvl - level
//
// @return - required experience value or -1.0 on fail
//
//native Float:aes_get_level_reqexp(level)
public Float:_mars_get_level_reqexp(level_index)
{
return float( level_reqexp( min( level_index, min( array_size-1, MAX_RANGS ) ) ) );
}

//native aes_get_level_for_exp(exp) AES 0.4
//
// Returns level for experience
// @exp - experience value
//
// @return - level num or -1 of fail
//
//native aes_get_exp_level(Float:exp)
public _mars_get_exp_level(Float:exp)
{
return get_level_index( floatround(exp) );
}

//
// Returns maximum level
//
//native aes_get_max_level()
public _mars_get_max_level()
{
return min(array_size, MAX_RANGS);
}

//
// Returns player experience
// @player - player id
//
// @return - player experience or -1.0 if player not tracked yet
//
//native Float:aes_get_player_exp(player)
public Float:_mars_get_player_exp(player_id)
{
if ( !IsEntPlayer(player_id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", player_id);
return -1.0;
}

return float(client_kills[player_id]);
}

//
// Returns player required experience to next level
// @player - player id
//
// @return - required experience value
//
//native Float:aes_get_player_reqexp(player)
public Float:_mars_get_player_reqexp(player_id)
{
if ( !IsEntPlayer(player_id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", player_id);
return -1.0;
}

return float( level_reqexp(client_level[ player_id ]) );
}

//native aes_set_player_stats(id,stats[3])
public _mars_get_player_stats(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}

new id = get_param(1);

if ( !IsEntPlayer(id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", id);
return 0;
}

new ret[4];

ret[0] = client_kills[id]; // exp
ret[1] = client_level[id];//get_level_index(ret[0]); // level
ret[2] = client_bonus[id];//313374; // bonus
ret[3] = level_reqexp(ret[1]); // next exp

set_array(2, ret, 4);

return 1;
}

//
// Returns current player level
// @player - player id
//
// @return - current player level or -1 if player not tracked yet
//
//native aes_get_player_level(player)
public _mars_get_player_level(player_id)
{
if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return -1;
}

return client_level[player_id];
}

// +
// Returns level name for level num.
//
// @level - level number
// @level[] - level name output
// @len - len
// @idLang - language id
//
// @return - len
//
//native aes_get_level_name(level,level_name[],len,idLang = LANG_SERVER)
public _mars_get_level_name(plugin,params)
{
if(params < 3)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 3, passed %d", params);

return 0;
}

new level_index = get_param(1);
new level_name[LEVEL_NAME_LENGHT];

ArrayGetString(rang_list, min(level_index,array_size-1), level_name, charsmax(level_name));

set_string(2, level_name, get_param(3));

return 1;
}

//
// Returns player bonus points
// @player - player id
//
// @return - player bonus points or -1 if player
//
//native aes_get_player_bonus(player)
public _mars_get_player_bonus(player_id)
{
if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return -1;
}

return client_bonus[player_id];
}

//
// Sets player bonus points
// @player - player id
// @bonus - bonus value
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
//
//native aes_set_player_bonus(player,bonus,bool:force = false)
public _mars_set_player_bonus(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}

new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}

client_bonus[player_id] = get_param(2);

return 1;
}

//
// Sets player level
// @player - player id
// @level - level
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
//
//native aes_set_player_level(player,level,bool:force = false)
public _mars_set_player_level(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}

new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}

client_level[player_id] = min( get_param(2), min(array_size, MAX_RANGS) );

return 1;
}

//
// Sets player experience
// @player - player id
// @exp - experience value
// @no_forward - dont trigger forward functions on level up or level down
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
// AES_RT_LEVLE_DOWN - on level down
// AES_RT_LEVEL_UP - on level up
//
//native aes_set_player_exp(player,Float:exp,bool:no_forward = false,bool:force = false)
public _mars_set_player_exp(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}

new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}

client_kills[player_id] = min( floatround(get_param_f(2)), mars_exp[MAX_RANGS-1] );

return 1;
}

//
// Thread search for aes stats witch given array track_ids
// @id - player id
// @track_ids - dynamic array with track ids for search
// @callback - your callback function
// public my_callback(id,Array:aes_stats,stats_data[])
// data[] - custom data
// @data_size - custom data size
//
// @return - true or false
//
//native aes_find_stats_thread(id = 0,Array:track_ids,callback[],data[] = "",datasize = 0)
public _mars_find_stats_thread() return false;


// aes exp cstrike

public Float:_mars_get_exp_for_stats_f(plugin_id,params)
{
if(params != 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d",params);
return 0.0;
}
return float(client_kills[get_param(1)]);//- 0.005; // в данный момент опыт и убийства - одно и тоже
}

public _mars_get_exp_for_stats(plugin_id,params)
{
if(params != 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d",params);
return 0;
}
return client_kills[get_param(1)];
}
#endif


Marslist.ini лежит в
\cstrike\addons\amxmodx\configs\
14 Ноя 2017
Код:
L 11/14/2017 - 18:37:43: [AMXX] Displaying debug trace (plugin "MARS_1.29Hz.amxx", version "1.29Hz")
L 11/14/2017 - 18:37:43: [AMXX] Run time error 4: index out of bounds
L 11/14/2017 - 18:37:43: [AMXX]    [0] MARS_1.29Hz.sma::get_player_stats (line 320)
L 11/14/2017 - 18:37:43: [AMXX]    [1] MARS_1.29Hz.sma::informer (line 263)
 

Анатолий

Пользователь
Регистрация
8 Июн 2017
Сообщения
582
Симпатии
189
Пол
Мужской
VKcom
e1337ace
#75
oqde, Понял проблему.... Проблема заключаеться в том что когда игрок даходит до маскимального уровня начинает в консоле выходит ошибки и у всех игроков пропадают звания

/**
* Micro Army Rank System by Ge3eR
* 13.11.2017
* v1.29Hz
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <csx> // По умолчанию включает и <csstats>. не трогать.
#if AMXX_VERSION_NUM < 183
#include <colorchat> // colorchat.inc от aghl.ru
#define MAX_NAME_LENGTH 32
#endif

/* Раскомментируйте, для частичной поддержки AES нативов и форвардов */
//#define AES_PLUGINS_COMPATIBLE

/* Раскомментируйте, если хотите дополнить HUD инфой о скилле */
#define WITH_SKILLS

/* -- READ_STATS
* Откуда будем считывать статистику?
* 0 - CSX or CSX Extended (Module)
* 1 - CSSTATS MYSQL by SKAJIbnEJIb // автором не тестировалось, но говорят норм )
* 2 - CSSTATSX SQL by serfreeman1337 + CSX_DUMMY Module// учтите, что CSSTATSX SQL должен быть в режиме csstats_sql_forwards 1
*/
#define READ_STATS 2

// Настройки отображения HUD информера
#define HUD_LIVE_COLOR_R 0
#define HUD_LIVE_COLOR_G 128
#define HUD_LIVE_COLOR_B 0
#define HUD_LIVE_AXIS_X 0.01
#define HUD_LIVE_AXIS_Y 0.22

#define HUD_SPEC_COLOR_R 28
#define HUD_SPEC_COLOR_G 90
#define HUD_SPEC_COLOR_B 28
#define HUD_SPEC_AXIS_X 0.01
#define HUD_SPEC_AXIS_Y 0.15

// Промежуток между сообщениями информера
#define HUD_REPEAT_TIME 1.5

/* -- LEVELUP_CONGRATULATION
* Оповещение о повышении уровня
* 0 - отключено
* 1 - включено (оповещает в чат, HUD и звуком)
*/
#define LEVELUP_CONGRATULATION 1

#if LEVELUP_CONGRATULATION == 1
// Настройки отображения HUD сообщения о повышении уровня
#define HUD_LEVELUP_COLOR_R 0
#define HUD_LEVELUP_COLOR_G 128
#define HUD_LEVELUP_COLOR_B 0
#define HUD_LEVELUP_AXIS_X -1.0
#define HUD_LEVELUP_AXIS_Y 0.15
#endif

#define ONSTART_WAIT_TIME /* CS */ 1.6 // задержка перед чтением статистики. (увеличить при плохом соединении с БД)

// автограф
#define PLAGIN "Micro Army Rank System"
#define VERSIA "1.29Hz"
#define AUTHOR "Ge3eR"

// остальное, системное
#if READ_STATS == 1
#include <csstats_mysql>
; // again ...
#endif
#if READ_STATS == 2
#include <csstatsx_sql> // и кто же это у нас пишет либы без semicolon?
; // hot fix by wopox1337
#endif

#if defined AES_PLUGINS_COMPATIBLE
new level_up_forward, dummy;
new client_bonus[33];
#endif

#pragma semicolon 1

#define STATS_KILLS 0
#define STATS_DEATHS 1
/*
#define STATS_HEADSHOTS 2
#define STATS_DAMAGE 6
*/
/* -- EXP_MODE .. будет в следующем релизе )
* Режим чтения опыта
* 0 - считать за опыт фраги (kills)
* 1 - считать за опыт хедшоты (headshots)
* 2 - считать за опыт общий урон (damage)
#define EXP_MODE 0
*/
#define MAX_RANGS sizeof mars_exp
#define IsEntPlayer(%1) (1<=%1<=g_maxplayers)

/* input: level
* output: next exp border
*///level_reqexp
#define level_reqexp(%1) mars_exp[min( (%1 + 1), min(array_size-1, MAX_RANGS) )]

#define LEVEL_NAME_LENGHT 64 // если ранг длинный и обрезается, изменить.

#define MARS_ST_EXP 0
#define MARS_ST_LEVEL 1
#define MARS_ST_NEXTEXP 2
#define MARS_ST_END_DIGIT 3

// ну вы поняли
new const prefix[] = "MARS";

#if defined WITH_SKILLS
new const skill_letters[][] =
{
"L-", "L", "L+", "M-", "M", "M+", "H-",
"H", "H+", "P-", "P", "P+", "G"
};
#endif

// Глобальные
new g_maxplayers;
new Array:rang_list;
new informer_sync_obj;
new array_size;

// оптимизируем запросы к стате засчитывая в оффлайн режиме)
new client_kills[33];
new client_kills_req[33];
new client_level[33];

#if defined WITH_SKILLS
#if READ_STATS == 0 || READ_STATS == 1
new client_deaths[33];
#endif
new Float:client_skill[33] = { 100.0, ... };
#endif

// Так быстрее вычислять ранг игрока. изменить по желанию.
new mars_exp[] = { // при добавлении последней записи, следите чтобы после неё небыло запятой
00000, 00002, 00005, 00010, 00015
}; // and so on, to infinity...

public plugin_init()
{
register_plugin(PLAGIN, VERSIA, AUTHOR);

rang_list = ArrayCreate(LEVEL_NAME_LENGHT);
informer_sync_obj = CreateHudSyncObj();
g_maxplayers = get_maxplayers();

register_srvcmd("mars_reload_list", "_mars_reload_list"); // Hot reload rank list
register_srvcmd("mars_reload_stats", "_mars_reload_stats"); // Hard reloading stats, for connected players

register_cvar("mars", VERSIA, FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED);

#if defined AES_PLUGINS_COMPATIBLE
level_up_forward = CreateMultiForward("aes_player_levelup",ET_IGNORE,FP_CELL,FP_CELL,FP_CELL);

if(get_cvar_pointer("aes_track_mode") == 0) register_cvar("aes_track_mode","0"); // "-1" ?
#endif

register_dictionary("mars.txt");

set_task(HUD_REPEAT_TIME, "informer", .flags="b");
}

public plugin_cfg()
{
server_print("[%s] Loaded %d Ranks", prefix, ( array_size = load_rangs() ) );
}

public _mars_reload_list()
{
ArrayClear(rang_list);
server_print("[%s] ReLoaded with %d Ranks", prefix, ( array_size = load_rangs() ) );

// пересчёт уровня. это понадобится, если новых уровней меньше чем было раньше // 1.28 bug fix
for(new id = 1; id <= g_maxplayers; id++)
if(is_user_connected(id))
client_level[id] = get_level_index(client_kills[id]);
}

load_rangs()
{
new file;
new lang[3];
new path[256], cfg_path[128];

get_configsdir(cfg_path,charsmax(cfg_path));
get_cvar_string("amx_language", lang, charsmax(lang));

format(path, charsmax(path), "%s/mars_lists/mars_list_%s.ini", cfg_path, lang);

if( !(file = fopen(path, "rt")))
{
format(path, charsmax(path), "%s/mars_list.ini", cfg_path);
file = fopen(path, "rt");
}

if(file)
{
new message[LEVEL_NAME_LENGHT];

while(!feof(file))
{
fgets(file, message, charsmax(message));
trim(message);
if(strlen(message) && message[0] != ';')
ArrayPushString(rang_list, message);
}
fclose(file);

new size = ArraySize(rang_list);
if(!size)
{
server_print("[%s] file^"%s^" is empty! Loaded 1 fake rank.", prefix, path);
ArrayPushString(rang_list, "Марсианин");

return 1;
}
return size;
}

server_print("[%s] File ^"%s^" not found! Loaded 1 fake rank.", prefix, path);
ArrayPushString(rang_list, "Марсианин");

return 1;
}

public informer()
{
static watching;
static stats[MARS_ST_END_DIGIT];
static level_name[LEVEL_NAME_LENGHT];
static output[96+ LEVEL_NAME_LENGHT];
static id;

#if defined WITH_SKILLS
static Float:skill;
#endif

for(id = 1; id <= g_maxplayers; id++)
{
if(!is_user_connected(id) || is_user_bot(id)) continue;

//entity_get_int(id, EV_INT_iuser2); // maybe engine?
watching = pev(id, pev_iuser2);

if(is_user_alive(watching) && !is_user_alive(id))
{
get_player_stats(watching, stats);

#if defined WITH_SKILLS
skill = _get_skill(watching);
#endif
}
else
{
get_player_stats(id, stats);

#if defined WITH_SKILLS
skill = _get_skill(id);
#endif
}

ArrayGetString(rang_list, stats[MARS_ST_LEVEL], level_name, charsmax(level_name));

#if defined WITH_SKILLS
format(output, charsmax(output), "%L^n%L^n%L"
, LANG_SERVER, "MARS_HUD_RANK"
, level_name

, LANG_SERVER, "MARS_HUD_EXP"
, stats[MARS_ST_EXP], max(stats[MARS_ST_EXP], stats[MARS_ST_NEXTEXP]) //Предела нет!

, LANG_SERVER, "MARS_HUD_SKILL"
, skill_letters[skill_id(
skill
)], skill
);
#else
format(output, charsmax(output), "%L^n%L"
, LANG_SERVER, "MARS_HUD_RANK"
, level_name

, LANG_SERVER, "MARS_HUD_EXP"
, stats[MARS_ST_EXP], max(stats[MARS_ST_EXP], stats[MARS_ST_NEXTEXP]) //Предела нет!
);
#endif

ClearSyncHud(id,informer_sync_obj);

if(is_user_alive(id))
{
set_hudmessage(HUD_LIVE_COLOR_R, HUD_LIVE_COLOR_G, HUD_LIVE_COLOR_B, HUD_LIVE_AXIS_X, HUD_LIVE_AXIS_Y, 0
, .holdtime = HUD_REPEAT_TIME, .channel = 3
, .fxtime=0.0, .fadeintime=0.1, .fadeouttime=0.1
);
}
else
{
set_hudmessage(HUD_SPEC_COLOR_R, HUD_SPEC_COLOR_G, HUD_SPEC_COLOR_B, HUD_SPEC_AXIS_X, HUD_SPEC_AXIS_Y, 0
, .holdtime = HUD_REPEAT_TIME, .channel = 3
, .fxtime=0.0, .fadeintime=0.1, .fadeouttime=0.1
);
}

ShowSyncHudMsg(id, informer_sync_obj, output);
}
}

get_player_stats(id, stats[])
{
stats[MARS_ST_EXP] = client_kills[id];
stats[MARS_ST_LEVEL] = client_level[id];
stats[MARS_ST_NEXTEXP] = level_reqexp(client_level[id]);
}

get_level_index(exp)
{
new index = 0;
for(new i = 0; i < array_size && i < MAX_RANGS; i++) // it works!
{
if(mars_exp <= exp)
index = i;
}
return index;
}


stock Float:_get_skill(id)
{
#if READ_STATS == 2
return client_skill[id];
#else
return effec(client_kills[id], client_deaths[id]);
#endif
}


stock Float:effec(kills, deaths) return (100.0 * float(kills) / float(kills + deaths));

stock skill_id(Float:skill)
{
#if READ_STATS == 2
switch(floatround(skill))
{
case 0..59: return 0; case 60..74: return 1; case 75..84: return 2; // L
case 85..99: return 3; case 100..114: return 4; case 115..129: return 5; // M
case 130..139: return 6; case 140..149: return 7; case 150..164: return 8; // H
case 165..179: return 9; case 180..194: return 10; case 195..209: return 11;// P
case 210..999: return 12; // G
}
#else // будет нормально отображать букву для простых смертных с READ_STATS 0
switch(floatround(skill))
{
case 0..14: return 0; case 15..29: return 1; case 30..44: return 2; // L
case 45..51: return 3; case 52..63: return 4; case 64..69: return 5; // M
case 70..74: return 6; case 75..79: return 7; case 80..85: return 8; // H
case 86..89: return 9; case 90..94: return 10; case 95..97: return 11;// P
case 98..100: return 12; // G
}
#endif
return 0;
}


public client_death(killer,victim)
{
if(!(IsEntPlayer(killer)) || !(IsEntPlayer(victim))
|| killer == victim
) return;


// зачтём
client_kills[killer]++;


#if defined WITH_SKILLS // немного больше вычислений...

#if READ_STATS == 0 || READ_STATS == 1
client_deaths[victim]++;
#endif


#if READ_STATS == 2 // The ELO Method

static Float:delta; delta = 1.0 / (1.0 + floatpower(10.0,(client_skill[killer] - client_skill[victim]) / 100.0));
static Float:koeff; koeff = 0.0;


if(client_kills[killer] < 100) koeff = 2.0; else koeff = 1.5;

client_skill[killer] += (koeff * delta);
client_skill[victim] -= (koeff * delta);


// log_amx("[MARS %d] %f (Client k)", killer, client_skill[killer]);
// log_amx("[MARS %d] %f (Client v)", victim, client_skill[victim]);


#endif

#endif

if(--client_kills_req[killer]) return; // пропускаем, пока игрок не достигнет нового уровня

// учтём
if(client_level[killer]< MAX_RANGS && client_level[killer]< array_size) client_level[killer]++;


client_kills_req[killer] = level_reqexp(client_level[killer])-client_kills[killer]; // 1.27 bug fixed

#if defined AES_PLUGINS_COMPATIBLE
// set event levelup
ExecuteForward(level_up_forward, dummy, killer, client_level[killer], client_level[killer] - 1);
#endif


// покажем
#if LEVELUP_CONGRATULATION == 1
static local_client_name[MAX_NAME_LENGTH];
static local_level_name[LEVEL_NAME_LENGHT];


get_user_name(killer, local_client_name,charsmax(local_client_name));
ArrayGetString(rang_list, client_level[killer], local_level_name, charsmax(local_level_name));


set_hudmessage(HUD_LEVELUP_COLOR_R, HUD_LEVELUP_COLOR_G, HUD_LEVELUP_COLOR_B, HUD_LEVELUP_AXIS_X, HUD_LEVELUP_AXIS_Y, 0,.holdtime = 8.0);
show_hudmessage(0, "%L", LANG_SERVER, "MARS_HUD_CONGRATULATION", local_client_name, local_level_name);


client_print_color(0, print_team_default
, "^4[^1%s^4] %L", prefix, LANG_SERVER, "MARS_TXT_CONGRATULATION", local_client_name, local_level_name);


client_cmd(0, "spk gonarch/gon_step1.wav");
#endif
}


public client_putinserver(id)
{
// немного подождём, а вдруг ещё не загрузилась инфа?
set_task(ONSTART_WAIT_TIME, "onstart_set_exp", id + 129);
}


public onstart_set_exp(index)
{
new id = index - 129;


if(!is_user_connected(id)) return;

// обнуляем
client_kills[id] = 0;


#if defined WITH_SKILLS
#if READ_STATS != 2
client_deaths[id] = 0;
#endif
client_skill[id] = 100.0;
#endif


#if defined AES_PLUGINS_COMPATIBLE
client_bonus[id] = 0;
#endif
// и считываем
_read_stats(id);
}


_read_stats(id)
{
#if READ_STATS == 0
static stats[8];
static bh[8];


if(!get_user_stats(id,stats,bh))
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif
#if READ_STATS == 1
static stats[22];


if(csstats_get_user_stats(id, stats) <= 0)
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif
#if READ_STATS == 2
static stats[8];
static bh[8];


if(!get_user_stats_sql(id,stats,bh))
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif


// оптимизируем подсчёт уровня
client_level[id] = get_level_index(client_kills[id]);
client_kills_req[id] = level_reqexp(get_level_index(client_kills[id]))-client_kills[id];


#if defined WITH_SKILLS

#if READ_STATS == 0 || READ_STATS == 1
client_deaths[id] = stats[STATS_DEATHS];
client_skill[id] = (100.0 * float(stats[STATS_KILLS]) / float(stats[STATS_KILLS] + stats[STATS_DEATHS]));
#endif


#if READ_STATS == 2
if(!get_user_skill(id,client_skill[id]))
client_skill[id] = 100.0;
if(!client_skill[id]) client_skill[id] = 100.0;
#endif
// log_amx("[MARS %d] %f (FirstRead)", id, client_skill[id]);
#endif
}
/*
#if AMXX_VERSION_NUM < 183
#define client_disconnected client_disconnect
#endif
public client_disconnected(id)
{
log_amx("[MARS %d] %f (Disconnect)", id, client_skill[id]);
}
*/


public _mars_reload_stats() /* постарайтесь не юзать эту функцию без надобности. Обновление статистики в модуле csx или других плагинах
не мгновенно, а зачастую настраивается на запись под конец карты или при дисконнекте. так что вы рискуете временно сбить счёт уже успевшим
его набить игрокам. */
{
for(new id = 1; id <= g_maxplayers; id++)
{
if(is_user_connected(id)) _read_stats(id);
}
server_print("stats reloaded");
}


// Проброс натив ... конец плагина )

public plugin_natives()
{
register_library("mars_main");


#if defined WITH_SKILLS
register_native("mars_get_skill", "_mars_get_skill", true); // get Real-Time skill
#endif


#if defined AES_PLUGINS_COMPATIBLE
register_library("mars_to_aes_main");


// Совместимость с плагинами использующими AES 0.5 Vega..
register_native("aes_get_player_level", "_mars_get_player_level", true);
register_native("aes_get_player_exp", "_mars_get_player_exp", true);
register_native("aes_get_player_reqexp", "_mars_get_player_reqexp", true);
register_native("aes_get_level_name", "_mars_get_level_name");
register_native("aes_get_level_reqexp", "_mars_get_level_reqexp", true);
register_native("aes_get_max_level", "_mars_get_max_level", true);
register_native("aes_get_exp_level", "_mars_get_exp_level", true);


// fake natives ?
register_native("aes_set_player_bonus", "_mars_set_player_bonus");
register_native("aes_get_player_bonus", "_mars_get_player_bonus", true);
register_native("aes_set_player_level", "_mars_set_player_level");
register_native("aes_set_player_exp", "_mars_set_player_exp");
// mega fake native :)
register_native("aes_find_stats_thread", "_mars_find_stats_thread"); // mega fake :D


// Совместимость с AES 0.4
register_native("aes_get_stats", "_mars_get_player_stats"); // do not use it anymore (in aes 0.5 Vega, will be return false)
register_native("aes_get_player_stats", "_mars_get_player_stats");
register_native("aes_get_exp_to_next_level","_mars_get_level_reqexp", true);
register_native("aes_get_level_for_exp", "_mars_get_exp_level", true);


// aes_cstrike_exp for AES: STATSX CSTRIKE plugin
register_native("aes_get_exp_for_stats_f","_mars_get_exp_for_stats_f");
register_native("aes_get_exp_for_stats","_mars_get_exp_for_stats");
#endif
}


#if defined WITH_SKILLS
public Float:_mars_get_skill(id)
{
if ( !IsEntPlayer(id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", id);
return -1.0;
}
return _get_skill(id);
}
#endif


#if defined AES_PLUGINS_COMPATIBLE
// Returns required experience to pass level
// @lvl - level
//
// @return - required experience value or -1.0 on fail
//
//native Float:aes_get_level_reqexp(level)
public Float:_mars_get_level_reqexp(level_index)
{
return float( level_reqexp( min( level_index, min( array_size-1, MAX_RANGS ) ) ) );
}


//native aes_get_level_for_exp(exp) AES 0.4
//
// Returns level for experience
// @exp - experience value
//
// @return - level num or -1 of fail
//
//native aes_get_exp_level(Float:exp)
public _mars_get_exp_level(Float:exp)
{
return get_level_index( floatround(exp) );
}


//
// Returns maximum level
//
//native aes_get_max_level()
public _mars_get_max_level()
{
return min(array_size, MAX_RANGS);
}


//
// Returns player experience
// @player - player id
//
// @return - player experience or -1.0 if player not tracked yet
//
//native Float:aes_get_player_exp(player)
public Float:_mars_get_player_exp(player_id)
{
if ( !IsEntPlayer(player_id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", player_id);
return -1.0;
}


return float(client_kills[player_id]);
}


//
// Returns player required experience to next level
// @player - player id
//
// @return - required experience value
//
//native Float:aes_get_player_reqexp(player)
public Float:_mars_get_player_reqexp(player_id)
{
if ( !IsEntPlayer(player_id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", player_id);
return -1.0;
}


return float( level_reqexp(client_level[ player_id ]) );
}


//native aes_set_player_stats(id,stats[3])
public _mars_get_player_stats(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}

new id = get_param(1);

if ( !IsEntPlayer(id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", id);
return 0;
}


new ret[4];

ret[0] = client_kills[id]; // exp
ret[1] = client_level[id];//get_level_index(ret[0]); // level
ret[2] = client_bonus[id];//313374; // bonus
ret[3] = level_reqexp(ret[1]); // next exp

set_array(2, ret, 4);

return 1;
}


//
// Returns current player level
// @player - player id
//
// @return - current player level or -1 if player not tracked yet
//
//native aes_get_player_level(player)
public _mars_get_player_level(player_id)
{
if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return -1;
}


return client_level[player_id];
}


// +
// Returns level name for level num.
//
// @level - level number
// @level[] - level name output
// @len - len
// @idLang - language id
//
// @return - len
//
//native aes_get_level_name(level,level_name[],len,idLang = LANG_SERVER)
public _mars_get_level_name(plugin,params)
{
if(params < 3)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 3, passed %d", params);

return 0;
}

new level_index = get_param(1);
new level_name[LEVEL_NAME_LENGHT];


ArrayGetString(rang_list, min(level_index,array_size-1), level_name, charsmax(level_name));

set_string(2, level_name, get_param(3));

return 1;
}


//
// Returns player bonus points
// @player - player id
//
// @return - player bonus points or -1 if player
//
//native aes_get_player_bonus(player)
public _mars_get_player_bonus(player_id)
{
if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return -1;
}


return client_bonus[player_id];
}


//
// Sets player bonus points
// @player - player id
// @bonus - bonus value
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
//
//native aes_set_player_bonus(player,bonus,bool:force = false)
public _mars_set_player_bonus(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}


new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}


client_bonus[player_id] = get_param(2);

return 1;
}


//
// Sets player level
// @player - player id
// @level - level
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
//
//native aes_set_player_level(player,level,bool:force = false)
public _mars_set_player_level(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}


new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}


client_level[player_id] = min( get_param(2), min(array_size, MAX_RANGS) );

return 1;
}


//
// Sets player experience
// @player - player id
// @exp - experience value
// @no_forward - dont trigger forward functions on level up or level down
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
// AES_RT_LEVLE_DOWN - on level down
// AES_RT_LEVEL_UP - on level up
//
//native aes_set_player_exp(player,Float:exp,bool:no_forward = false,bool:force = false)
public _mars_set_player_exp(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}


new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}


client_kills[player_id] = min( floatround(get_param_f(2)), mars_exp[MAX_RANGS-1] );

return 1;
}


//
// Thread search for aes stats witch given array track_ids
// @id - player id
// @track_ids - dynamic array with track ids for search
// @callback - your callback function
// public my_callback(id,Array:aes_stats,stats_data[])
// data[] - custom data
// @data_size - custom data size
//
// @return - true or false
//
//native aes_find_stats_thread(id = 0,Array:track_ids,callback[],data[] = "",datasize = 0)
public _mars_find_stats_thread() return false;



// aes exp cstrike

public Float:_mars_get_exp_for_stats_f(plugin_id,params)
{
if(params != 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d",params);
return 0.0;
}
return float(client_kills[get_param(1)]);//- 0.005; // в данный момент опыт и убийства - одно и тоже
}


public _mars_get_exp_for_stats(plugin_id,params)
{
if(params != 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d",params);
return 0;
}
return client_kills[get_param(1)];
}
#endif

Marslist.ini лежит в
\cstrike\addons\amxmodx\configs\
14 Ноя 2017
Код:
L 11/14/2017 - 18:37:43: [AMXX] Displaying debug trace (plugin "MARS_1.29Hz.amxx", version "1.29Hz")
L 11/14/2017 - 18:37:43: [AMXX] Run time error 4: index out of bounds
L 11/14/2017 - 18:37:43: [AMXX]    [0] MARS_1.29Hz.sma::get_player_stats (line 320)
L 11/14/2017 - 18:37:43: [AMXX]    [1] MARS_1.29Hz.sma::informer (line 263)
ну хотя бы мой плаг этого лишен) хотя недочетов много но зато работает как часика) да и как то играл на 1 сервере там ваще брел званий) весь вмысл теряется) типа часик отыграл) месный барыга и тогдалее) на что фантазия людям))
14 Ноя 2017
ну хотя бы мой плаг этого лишен) хотя недочетов много но зато работает как часика) да и как то играл на 1 сервере там ваще брел званий) весь вмысл теряется) типа часик отыграл) месный барыга и тогдалее) на что фантазия людям))
стоит кое где while заменить на if как проблема с ласт званием пропадает! как этого не заметили все остальные мододелы?? эта проблема ваще во всех ска званиях! aes не тестил! про него не говорю! может оно и правильно while но смотря при каком условии! методам тыка поставил if и проблемы нет)
 

Анатолий

Пользователь
Регистрация
8 Июн 2017
Сообщения
582
Симпатии
189
Пол
Мужской
VKcom
e1337ace
#76
да и по плагину не сказать что это микро ранг) если такой знаток то лучше с 0 написать норм плагин чем подстраивать свой под все что только можно! лучше что то реально микро но не зависимое от остальных модов. а совместимость как плюсом делать тогда уж) просто если ставить aes то твой плгин просто не нужен! раз есть полноценный aes а как замена это бред! 1 менять на 1? = 1))
 

oqde

Пользователь
Регистрация
20 Окт 2017
Сообщения
47
Симпатии
14
#77
да и по плагину не сказать что это микро ранг) если такой знаток то лучше с 0 написать норм плагин чем подстраивать свой под все что только можно! лучше что то реально микро но не зависимое от остальных модов. а совместимость как плюсом делать тогда уж) просто если ставить aes то твой плгин просто не нужен! раз есть полноценный aes а как замена это бред! 1 менять на 1? = 1))
имеете свой плагин рангов? поздравляю. но будте любезны иметь честь не срать в чужих топиках, не по понятиям выходит.
 

oqde

Пользователь
Регистрация
20 Окт 2017
Сообщения
47
Симпатии
14
#78
oqde, Понял проблему.... Проблема заключаеться в том что когда игрок даходит до маскимального уровня начинает в консоле выходит ошибки и у всех игроков пропадают звания

/**
* Micro Army Rank System by Ge3eR
* 13.11.2017
* v1.29Hz
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <csx> // По умолчанию включает и <csstats>. не трогать.
#if AMXX_VERSION_NUM < 183
#include <colorchat> // colorchat.inc от aghl.ru
#define MAX_NAME_LENGTH 32
#endif

/* Раскомментируйте, для частичной поддержки AES нативов и форвардов */
//#define AES_PLUGINS_COMPATIBLE

/* Раскомментируйте, если хотите дополнить HUD инфой о скилле */
#define WITH_SKILLS

/* -- READ_STATS
* Откуда будем считывать статистику?
* 0 - CSX or CSX Extended (Module)
* 1 - CSSTATS MYSQL by SKAJIbnEJIb // автором не тестировалось, но говорят норм )
* 2 - CSSTATSX SQL by serfreeman1337 + CSX_DUMMY Module// учтите, что CSSTATSX SQL должен быть в режиме csstats_sql_forwards 1
*/
#define READ_STATS 2

// Настройки отображения HUD информера
#define HUD_LIVE_COLOR_R 0
#define HUD_LIVE_COLOR_G 128
#define HUD_LIVE_COLOR_B 0
#define HUD_LIVE_AXIS_X 0.01
#define HUD_LIVE_AXIS_Y 0.22

#define HUD_SPEC_COLOR_R 28
#define HUD_SPEC_COLOR_G 90
#define HUD_SPEC_COLOR_B 28
#define HUD_SPEC_AXIS_X 0.01
#define HUD_SPEC_AXIS_Y 0.15

// Промежуток между сообщениями информера
#define HUD_REPEAT_TIME 1.5

/* -- LEVELUP_CONGRATULATION
* Оповещение о повышении уровня
* 0 - отключено
* 1 - включено (оповещает в чат, HUD и звуком)
*/
#define LEVELUP_CONGRATULATION 1

#if LEVELUP_CONGRATULATION == 1
// Настройки отображения HUD сообщения о повышении уровня
#define HUD_LEVELUP_COLOR_R 0
#define HUD_LEVELUP_COLOR_G 128
#define HUD_LEVELUP_COLOR_B 0
#define HUD_LEVELUP_AXIS_X -1.0
#define HUD_LEVELUP_AXIS_Y 0.15
#endif

#define ONSTART_WAIT_TIME /* CS */ 1.6 // задержка перед чтением статистики. (увеличить при плохом соединении с БД)

// автограф
#define PLAGIN "Micro Army Rank System"
#define VERSIA "1.29Hz"
#define AUTHOR "Ge3eR"

// остальное, системное
#if READ_STATS == 1
#include <csstats_mysql>
; // again ...
#endif
#if READ_STATS == 2
#include <csstatsx_sql> // и кто же это у нас пишет либы без semicolon?
; // hot fix by wopox1337
#endif

#if defined AES_PLUGINS_COMPATIBLE
new level_up_forward, dummy;
new client_bonus[33];
#endif

#pragma semicolon 1

#define STATS_KILLS 0
#define STATS_DEATHS 1
/*
#define STATS_HEADSHOTS 2
#define STATS_DAMAGE 6
*/
/* -- EXP_MODE .. будет в следующем релизе )
* Режим чтения опыта
* 0 - считать за опыт фраги (kills)
* 1 - считать за опыт хедшоты (headshots)
* 2 - считать за опыт общий урон (damage)
#define EXP_MODE 0
*/
#define MAX_RANGS sizeof mars_exp
#define IsEntPlayer(%1) (1<=%1<=g_maxplayers)

/* input: level
* output: next exp border
*///level_reqexp
#define level_reqexp(%1) mars_exp[min( (%1 + 1), min(array_size-1, MAX_RANGS) )]

#define LEVEL_NAME_LENGHT 64 // если ранг длинный и обрезается, изменить.

#define MARS_ST_EXP 0
#define MARS_ST_LEVEL 1
#define MARS_ST_NEXTEXP 2
#define MARS_ST_END_DIGIT 3

// ну вы поняли
new const prefix[] = "MARS";

#if defined WITH_SKILLS
new const skill_letters[][] =
{
"L-", "L", "L+", "M-", "M", "M+", "H-",
"H", "H+", "P-", "P", "P+", "G"
};
#endif

// Глобальные
new g_maxplayers;
new Array:rang_list;
new informer_sync_obj;
new array_size;

// оптимизируем запросы к стате засчитывая в оффлайн режиме)
new client_kills[33];
new client_kills_req[33];
new client_level[33];

#if defined WITH_SKILLS
#if READ_STATS == 0 || READ_STATS == 1
new client_deaths[33];
#endif
new Float:client_skill[33] = { 100.0, ... };
#endif

// Так быстрее вычислять ранг игрока. изменить по желанию.
new mars_exp[] = { // при добавлении последней записи, следите чтобы после неё небыло запятой
00000, 00002, 00005, 00010, 00015
}; // and so on, to infinity...

public plugin_init()
{
register_plugin(PLAGIN, VERSIA, AUTHOR);

rang_list = ArrayCreate(LEVEL_NAME_LENGHT);
informer_sync_obj = CreateHudSyncObj();
g_maxplayers = get_maxplayers();

register_srvcmd("mars_reload_list", "_mars_reload_list"); // Hot reload rank list
register_srvcmd("mars_reload_stats", "_mars_reload_stats"); // Hard reloading stats, for connected players

register_cvar("mars", VERSIA, FCVAR_SERVER | FCVAR_SPONLY | FCVAR_UNLOGGED);

#if defined AES_PLUGINS_COMPATIBLE
level_up_forward = CreateMultiForward("aes_player_levelup",ET_IGNORE,FP_CELL,FP_CELL,FP_CELL);

if(get_cvar_pointer("aes_track_mode") == 0) register_cvar("aes_track_mode","0"); // "-1" ?
#endif

register_dictionary("mars.txt");

set_task(HUD_REPEAT_TIME, "informer", .flags="b");
}

public plugin_cfg()
{
server_print("[%s] Loaded %d Ranks", prefix, ( array_size = load_rangs() ) );
}

public _mars_reload_list()
{
ArrayClear(rang_list);
server_print("[%s] ReLoaded with %d Ranks", prefix, ( array_size = load_rangs() ) );

// пересчёт уровня. это понадобится, если новых уровней меньше чем было раньше // 1.28 bug fix
for(new id = 1; id <= g_maxplayers; id++)
if(is_user_connected(id))
client_level[id] = get_level_index(client_kills[id]);
}

load_rangs()
{
new file;
new lang[3];
new path[256], cfg_path[128];

get_configsdir(cfg_path,charsmax(cfg_path));
get_cvar_string("amx_language", lang, charsmax(lang));

format(path, charsmax(path), "%s/mars_lists/mars_list_%s.ini", cfg_path, lang);

if( !(file = fopen(path, "rt")))
{
format(path, charsmax(path), "%s/mars_list.ini", cfg_path);
file = fopen(path, "rt");
}

if(file)
{
new message[LEVEL_NAME_LENGHT];

while(!feof(file))
{
fgets(file, message, charsmax(message));
trim(message);
if(strlen(message) && message[0] != ';')
ArrayPushString(rang_list, message);
}
fclose(file);

new size = ArraySize(rang_list);
if(!size)
{
server_print("[%s] file^"%s^" is empty! Loaded 1 fake rank.", prefix, path);
ArrayPushString(rang_list, "Марсианин");

return 1;
}
return size;
}

server_print("[%s] File ^"%s^" not found! Loaded 1 fake rank.", prefix, path);
ArrayPushString(rang_list, "Марсианин");

return 1;
}

public informer()
{
static watching;
static stats[MARS_ST_END_DIGIT];
static level_name[LEVEL_NAME_LENGHT];
static output[96+ LEVEL_NAME_LENGHT];
static id;

#if defined WITH_SKILLS
static Float:skill;
#endif

for(id = 1; id <= g_maxplayers; id++)
{
if(!is_user_connected(id) || is_user_bot(id)) continue;

//entity_get_int(id, EV_INT_iuser2); // maybe engine?
watching = pev(id, pev_iuser2);

if(is_user_alive(watching) && !is_user_alive(id))
{
get_player_stats(watching, stats);

#if defined WITH_SKILLS
skill = _get_skill(watching);
#endif
}
else
{
get_player_stats(id, stats);

#if defined WITH_SKILLS
skill = _get_skill(id);
#endif
}

ArrayGetString(rang_list, stats[MARS_ST_LEVEL], level_name, charsmax(level_name));

#if defined WITH_SKILLS
format(output, charsmax(output), "%L^n%L^n%L"
, LANG_SERVER, "MARS_HUD_RANK"
, level_name

, LANG_SERVER, "MARS_HUD_EXP"
, stats[MARS_ST_EXP], max(stats[MARS_ST_EXP], stats[MARS_ST_NEXTEXP]) //Предела нет!

, LANG_SERVER, "MARS_HUD_SKILL"
, skill_letters[skill_id(
skill
)], skill
);
#else
format(output, charsmax(output), "%L^n%L"
, LANG_SERVER, "MARS_HUD_RANK"
, level_name

, LANG_SERVER, "MARS_HUD_EXP"
, stats[MARS_ST_EXP], max(stats[MARS_ST_EXP], stats[MARS_ST_NEXTEXP]) //Предела нет!
);
#endif

ClearSyncHud(id,informer_sync_obj);

if(is_user_alive(id))
{
set_hudmessage(HUD_LIVE_COLOR_R, HUD_LIVE_COLOR_G, HUD_LIVE_COLOR_B, HUD_LIVE_AXIS_X, HUD_LIVE_AXIS_Y, 0
, .holdtime = HUD_REPEAT_TIME, .channel = 3
, .fxtime=0.0, .fadeintime=0.1, .fadeouttime=0.1
);
}
else
{
set_hudmessage(HUD_SPEC_COLOR_R, HUD_SPEC_COLOR_G, HUD_SPEC_COLOR_B, HUD_SPEC_AXIS_X, HUD_SPEC_AXIS_Y, 0
, .holdtime = HUD_REPEAT_TIME, .channel = 3
, .fxtime=0.0, .fadeintime=0.1, .fadeouttime=0.1
);
}

ShowSyncHudMsg(id, informer_sync_obj, output);
}
}

get_player_stats(id, stats[])
{
stats[MARS_ST_EXP] = client_kills[id];
stats[MARS_ST_LEVEL] = client_level[id];
stats[MARS_ST_NEXTEXP] = level_reqexp(client_level[id]);
}

get_level_index(exp)
{
new index = 0;
for(new i = 0; i < array_size && i < MAX_RANGS; i++) // it works!
{
if(mars_exp <= exp)
index = i;
}
return index;
}


stock Float:_get_skill(id)
{
#if READ_STATS == 2
return client_skill[id];
#else
return effec(client_kills[id], client_deaths[id]);
#endif
}


stock Float:effec(kills, deaths) return (100.0 * float(kills) / float(kills + deaths));

stock skill_id(Float:skill)
{
#if READ_STATS == 2
switch(floatround(skill))
{
case 0..59: return 0; case 60..74: return 1; case 75..84: return 2; // L
case 85..99: return 3; case 100..114: return 4; case 115..129: return 5; // M
case 130..139: return 6; case 140..149: return 7; case 150..164: return 8; // H
case 165..179: return 9; case 180..194: return 10; case 195..209: return 11;// P
case 210..999: return 12; // G
}
#else // будет нормально отображать букву для простых смертных с READ_STATS 0
switch(floatround(skill))
{
case 0..14: return 0; case 15..29: return 1; case 30..44: return 2; // L
case 45..51: return 3; case 52..63: return 4; case 64..69: return 5; // M
case 70..74: return 6; case 75..79: return 7; case 80..85: return 8; // H
case 86..89: return 9; case 90..94: return 10; case 95..97: return 11;// P
case 98..100: return 12; // G
}
#endif
return 0;
}


public client_death(killer,victim)
{
if(!(IsEntPlayer(killer)) || !(IsEntPlayer(victim))
|| killer == victim
) return;


// зачтём
client_kills[killer]++;


#if defined WITH_SKILLS // немного больше вычислений...

#if READ_STATS == 0 || READ_STATS == 1
client_deaths[victim]++;
#endif


#if READ_STATS == 2 // The ELO Method

static Float:delta; delta = 1.0 / (1.0 + floatpower(10.0,(client_skill[killer] - client_skill[victim]) / 100.0));
static Float:koeff; koeff = 0.0;


if(client_kills[killer] < 100) koeff = 2.0; else koeff = 1.5;

client_skill[killer] += (koeff * delta);
client_skill[victim] -= (koeff * delta);


// log_amx("[MARS %d] %f (Client k)", killer, client_skill[killer]);
// log_amx("[MARS %d] %f (Client v)", victim, client_skill[victim]);


#endif

#endif

if(--client_kills_req[killer]) return; // пропускаем, пока игрок не достигнет нового уровня

// учтём
if(client_level[killer]< MAX_RANGS && client_level[killer]< array_size) client_level[killer]++;


client_kills_req[killer] = level_reqexp(client_level[killer])-client_kills[killer]; // 1.27 bug fixed

#if defined AES_PLUGINS_COMPATIBLE
// set event levelup
ExecuteForward(level_up_forward, dummy, killer, client_level[killer], client_level[killer] - 1);
#endif


// покажем
#if LEVELUP_CONGRATULATION == 1
static local_client_name[MAX_NAME_LENGTH];
static local_level_name[LEVEL_NAME_LENGHT];


get_user_name(killer, local_client_name,charsmax(local_client_name));
ArrayGetString(rang_list, client_level[killer], local_level_name, charsmax(local_level_name));


set_hudmessage(HUD_LEVELUP_COLOR_R, HUD_LEVELUP_COLOR_G, HUD_LEVELUP_COLOR_B, HUD_LEVELUP_AXIS_X, HUD_LEVELUP_AXIS_Y, 0,.holdtime = 8.0);
show_hudmessage(0, "%L", LANG_SERVER, "MARS_HUD_CONGRATULATION", local_client_name, local_level_name);


client_print_color(0, print_team_default
, "^4[^1%s^4] %L", prefix, LANG_SERVER, "MARS_TXT_CONGRATULATION", local_client_name, local_level_name);


client_cmd(0, "spk gonarch/gon_step1.wav");
#endif
}


public client_putinserver(id)
{
// немного подождём, а вдруг ещё не загрузилась инфа?
set_task(ONSTART_WAIT_TIME, "onstart_set_exp", id + 129);
}


public onstart_set_exp(index)
{
new id = index - 129;


if(!is_user_connected(id)) return;

// обнуляем
client_kills[id] = 0;


#if defined WITH_SKILLS
#if READ_STATS != 2
client_deaths[id] = 0;
#endif
client_skill[id] = 100.0;
#endif


#if defined AES_PLUGINS_COMPATIBLE
client_bonus[id] = 0;
#endif
// и считываем
_read_stats(id);
}


_read_stats(id)
{
#if READ_STATS == 0
static stats[8];
static bh[8];


if(!get_user_stats(id,stats,bh))
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif
#if READ_STATS == 1
static stats[22];


if(csstats_get_user_stats(id, stats) <= 0)
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif
#if READ_STATS == 2
static stats[8];
static bh[8];


if(!get_user_stats_sql(id,stats,bh))
client_kills[id] = 0;
else
client_kills[id] = stats[STATS_KILLS];
#endif


// оптимизируем подсчёт уровня
client_level[id] = get_level_index(client_kills[id]);
client_kills_req[id] = level_reqexp(get_level_index(client_kills[id]))-client_kills[id];


#if defined WITH_SKILLS

#if READ_STATS == 0 || READ_STATS == 1
client_deaths[id] = stats[STATS_DEATHS];
client_skill[id] = (100.0 * float(stats[STATS_KILLS]) / float(stats[STATS_KILLS] + stats[STATS_DEATHS]));
#endif


#if READ_STATS == 2
if(!get_user_skill(id,client_skill[id]))
client_skill[id] = 100.0;
if(!client_skill[id]) client_skill[id] = 100.0;
#endif
// log_amx("[MARS %d] %f (FirstRead)", id, client_skill[id]);
#endif
}
/*
#if AMXX_VERSION_NUM < 183
#define client_disconnected client_disconnect
#endif
public client_disconnected(id)
{
log_amx("[MARS %d] %f (Disconnect)", id, client_skill[id]);
}
*/


public _mars_reload_stats() /* постарайтесь не юзать эту функцию без надобности. Обновление статистики в модуле csx или других плагинах
не мгновенно, а зачастую настраивается на запись под конец карты или при дисконнекте. так что вы рискуете временно сбить счёт уже успевшим
его набить игрокам. */
{
for(new id = 1; id <= g_maxplayers; id++)
{
if(is_user_connected(id)) _read_stats(id);
}
server_print("stats reloaded");
}


// Проброс натив ... конец плагина )

public plugin_natives()
{
register_library("mars_main");


#if defined WITH_SKILLS
register_native("mars_get_skill", "_mars_get_skill", true); // get Real-Time skill
#endif


#if defined AES_PLUGINS_COMPATIBLE
register_library("mars_to_aes_main");


// Совместимость с плагинами использующими AES 0.5 Vega..
register_native("aes_get_player_level", "_mars_get_player_level", true);
register_native("aes_get_player_exp", "_mars_get_player_exp", true);
register_native("aes_get_player_reqexp", "_mars_get_player_reqexp", true);
register_native("aes_get_level_name", "_mars_get_level_name");
register_native("aes_get_level_reqexp", "_mars_get_level_reqexp", true);
register_native("aes_get_max_level", "_mars_get_max_level", true);
register_native("aes_get_exp_level", "_mars_get_exp_level", true);


// fake natives ?
register_native("aes_set_player_bonus", "_mars_set_player_bonus");
register_native("aes_get_player_bonus", "_mars_get_player_bonus", true);
register_native("aes_set_player_level", "_mars_set_player_level");
register_native("aes_set_player_exp", "_mars_set_player_exp");
// mega fake native :)
register_native("aes_find_stats_thread", "_mars_find_stats_thread"); // mega fake :D


// Совместимость с AES 0.4
register_native("aes_get_stats", "_mars_get_player_stats"); // do not use it anymore (in aes 0.5 Vega, will be return false)
register_native("aes_get_player_stats", "_mars_get_player_stats");
register_native("aes_get_exp_to_next_level","_mars_get_level_reqexp", true);
register_native("aes_get_level_for_exp", "_mars_get_exp_level", true);


// aes_cstrike_exp for AES: STATSX CSTRIKE plugin
register_native("aes_get_exp_for_stats_f","_mars_get_exp_for_stats_f");
register_native("aes_get_exp_for_stats","_mars_get_exp_for_stats");
#endif
}


#if defined WITH_SKILLS
public Float:_mars_get_skill(id)
{
if ( !IsEntPlayer(id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", id);
return -1.0;
}
return _get_skill(id);
}
#endif


#if defined AES_PLUGINS_COMPATIBLE
// Returns required experience to pass level
// @lvl - level
//
// @return - required experience value or -1.0 on fail
//
//native Float:aes_get_level_reqexp(level)
public Float:_mars_get_level_reqexp(level_index)
{
return float( level_reqexp( min( level_index, min( array_size-1, MAX_RANGS ) ) ) );
}


//native aes_get_level_for_exp(exp) AES 0.4
//
// Returns level for experience
// @exp - experience value
//
// @return - level num or -1 of fail
//
//native aes_get_exp_level(Float:exp)
public _mars_get_exp_level(Float:exp)
{
return get_level_index( floatround(exp) );
}


//
// Returns maximum level
//
//native aes_get_max_level()
public _mars_get_max_level()
{
return min(array_size, MAX_RANGS);
}


//
// Returns player experience
// @player - player id
//
// @return - player experience or -1.0 if player not tracked yet
//
//native Float:aes_get_player_exp(player)
public Float:_mars_get_player_exp(player_id)
{
if ( !IsEntPlayer(player_id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", player_id);
return -1.0;
}


return float(client_kills[player_id]);
}


//
// Returns player required experience to next level
// @player - player id
//
// @return - required experience value
//
//native Float:aes_get_player_reqexp(player)
public Float:_mars_get_player_reqexp(player_id)
{
if ( !IsEntPlayer(player_id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", player_id);
return -1.0;
}


return float( level_reqexp(client_level[ player_id ]) );
}


//native aes_set_player_stats(id,stats[3])
public _mars_get_player_stats(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}

new id = get_param(1);

if ( !IsEntPlayer(id) )
{
log_error(AMX_ERR_NATIVE, "player out of range (%d)", id);
return 0;
}


new ret[4];

ret[0] = client_kills[id]; // exp
ret[1] = client_level[id];//get_level_index(ret[0]); // level
ret[2] = client_bonus[id];//313374; // bonus
ret[3] = level_reqexp(ret[1]); // next exp

set_array(2, ret, 4);

return 1;
}


//
// Returns current player level
// @player - player id
//
// @return - current player level or -1 if player not tracked yet
//
//native aes_get_player_level(player)
public _mars_get_player_level(player_id)
{
if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return -1;
}


return client_level[player_id];
}


// +
// Returns level name for level num.
//
// @level - level number
// @level[] - level name output
// @len - len
// @idLang - language id
//
// @return - len
//
//native aes_get_level_name(level,level_name[],len,idLang = LANG_SERVER)
public _mars_get_level_name(plugin,params)
{
if(params < 3)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 3, passed %d", params);

return 0;
}

new level_index = get_param(1);
new level_name[LEVEL_NAME_LENGHT];


ArrayGetString(rang_list, min(level_index,array_size-1), level_name, charsmax(level_name));

set_string(2, level_name, get_param(3));

return 1;
}


//
// Returns player bonus points
// @player - player id
//
// @return - player bonus points or -1 if player
//
//native aes_get_player_bonus(player)
public _mars_get_player_bonus(player_id)
{
if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return -1;
}


return client_bonus[player_id];
}


//
// Sets player bonus points
// @player - player id
// @bonus - bonus value
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
//
//native aes_set_player_bonus(player,bonus,bool:force = false)
public _mars_set_player_bonus(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}


new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}


client_bonus[player_id] = get_param(2);

return 1;
}


//
// Sets player level
// @player - player id
// @level - level
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
//
//native aes_set_player_level(player,level,bool:force = false)
public _mars_set_player_level(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}


new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}


client_level[player_id] = min( get_param(2), min(array_size, MAX_RANGS) );

return 1;
}


//
// Sets player experience
// @player - player id
// @exp - experience value
// @no_forward - dont trigger forward functions on level up or level down
// @force - force even if track paused
//
// @return
// AES_RT_NO - on track pause or player not tracked yet
// AES_RT_YES - on success
// AES_RT_LEVLE_DOWN - on level down
// AES_RT_LEVEL_UP - on level up
//
//native aes_set_player_exp(player,Float:exp,bool:no_forward = false,bool:force = false)
public _mars_set_player_exp(plugin,params)
{
if(params < 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d", params);

return 0;
}


new player_id = get_param(1);

if(!IsEntPlayer(player_id))
{
log_error(AMX_ERR_NATIVE,"player index %d, out of bounds", player_id);

return 0;
}


client_kills[player_id] = min( floatround(get_param_f(2)), mars_exp[MAX_RANGS-1] );

return 1;
}


//
// Thread search for aes stats witch given array track_ids
// @id - player id
// @track_ids - dynamic array with track ids for search
// @callback - your callback function
// public my_callback(id,Array:aes_stats,stats_data[])
// data[] - custom data
// @data_size - custom data size
//
// @return - true or false
//
//native aes_find_stats_thread(id = 0,Array:track_ids,callback[],data[] = "",datasize = 0)
public _mars_find_stats_thread() return false;



// aes exp cstrike

public Float:_mars_get_exp_for_stats_f(plugin_id,params)
{
if(params != 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d",params);
return 0.0;
}
return float(client_kills[get_param(1)]);//- 0.005; // в данный момент опыт и убийства - одно и тоже
}


public _mars_get_exp_for_stats(plugin_id,params)
{
if(params != 2)
{
log_error(AMX_ERR_NATIVE,"bad arguments num, expected 2, passed %d",params);
return 0;
}
return client_kills[get_param(1)];
}
#endif

Marslist.ini лежит в
\cstrike\addons\amxmodx\configs\
14 Ноя 2017
Код:
L 11/14/2017 - 18:37:43: [AMXX] Displaying debug trace (plugin "MARS_1.29Hz.amxx", version "1.29Hz")
L 11/14/2017 - 18:37:43: [AMXX] Run time error 4: index out of bounds
L 11/14/2017 - 18:37:43: [AMXX]    [0] MARS_1.29Hz.sma::get_player_stats (line 320)
L 11/14/2017 - 18:37:43: [AMXX]    [1] MARS_1.29Hz.sma::informer (line 263)
ошибка неприятная, но не критичная. всё будет продолжать работать для других игроков.
увеличте количество записей в mars_exp[]

благодарю за лог ошибок)
14 Ноя 2017
На самом деле, за эти 2 недели множество ребят непереставая шлют мне логи, и я благодарен им за это. Благодаря вам, ребята, плагин становится всё лучше и лучше с каждым днём, и уже намного опережает конкурентов (которые злятся :) )
Учесть всех-всех ситуаций невозможно, в этом и суть разработки.
Гораздо важнее, что все ошибки учитываются и исправляются в новых версиях.
 

oqde

Пользователь
Регистрация
20 Окт 2017
Сообщения
47
Симпатии
14
#79
т.е. анеш бонус что ли? я имел ввиду за звания, был ты рядовой достиг там допустим лейтенанта и т.д. и тебе за это достижения звания, как ты его достиг, ввиде бонуса деньга еще выдалась)) как то так))):confused::)
Держи))
Код:
#include <amxmodx>
#include <cstrike>
#if AMXX_VERSION_NUM < 183
    #include <colorchat> // от aghl.ru
#endif

// [MARS] Микро Награды!
// для работы с MARS 1.29Hz, вам необходимо включить совместимость c AES
//
// Вызывается, когда игрок поднял ранг.
//
forward aes_player_levelup(id,new_level,old_level)

#define MONEY_AWARD 1000 // Денюжка в долларах, при поднятии ранга

new const prefix[] = "MARS";

public plugin_init()
    register_plugin("MARS: AWARDS!", "0.1Hz", "Ge3eR");

public aes_player_levelup(id)
{
    if(!is_user_connected(id)) return;

    cs_set_user_money(id, min(cs_get_user_money(id) + MONEY_AWARD, 16000));

    client_print_color(0, print_team_default
        , "^4[^1%s^4] ^3Вы ^1подняли ^3ранг!^1 Ваша награда: ^4%d$", prefix, MONEY_AWARD);
}
 

ade888

Пользователь
Регистрация
9 Июн 2017
Сообщения
184
Симпатии
24
Пол
Мужской
#80
ошибка неприятная, но не критичная. всё будет продолжать работать для других игроков.
увеличте количество записей в mars_exp[]

благодарю за лог ошибок)
14 Ноя 2017
На самом деле, за эти 2 недели множество ребят непереставая шлют мне логи, и я благодарен им за это. Благодаря вам, ребята, плагин становится всё лучше и лучше с каждым днём, и уже намного опережает конкурентов (которые злятся :) )
Учесть всех-всех ситуаций невозможно, в этом и суть разработки.
Гораздо важнее, что все ошибки учитываются и исправляются в новых версиях.
Это мне понятно что надо польше опыта делать для того чтоб званий было больше , но проблема том что когда звание приходит к тупику весь плагин не рабочий, я поему сделал мадо зван й для проверки того по каким причинам он перестает работать,