Spring

Плагин АМХХ Spring 2.0.6

Нет прав для скачивания
C++:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#include <engine>

#if !defined MAX_MAPNAME_LENGTH
#define MAX_MAPNAME_LENGTH 64
#endif

//Необходимые сonst для разных предназначений
new const PLUGIN[] = "Spring";
new const VERSION[] = "2.0";
new const AUTHOR[] = "wellasgood";

new const ACCESS_MENU_FLAG = ADMIN_CFG; //для доступа (главное меню, создание и тп)
new const ACCESS_ADMIN_FLAG = ADMIN_BAN; //если использование прыжка только для админов (также фигурирует в доступе к главному меню, перемещение для админов)
new const ACCESS_VIP_FLAG = ADMIN_LEVEL_H; //для подстановки в коде! (флаг который есть у випов на вашем сервере!)
new const ACCESS_MULTI_FLAG = (ADMIN_BAN|ADMIN_LEVEL_H); //мульти флаг (на данном примере будет разрешено использование только админам и вип)
new const ACCESS_CAGE_FLAG = ADMIN_IMMUNITY; //флаг для иммунитета от перемещения в клетку. (игрок будет прозрачным от нажатия в меню)

new const SPRING_SND[] = "spring/spring.wav";

new const SPRING_MDL[] = "models/spring/spring.mdl";
new const SPRING_CAGE1_MDL[] = "models/spring/Cage_1.mdl";
new const SPRING_CAGE2_MDL[] = "models/spring/Cage_2.mdl";
new const SPRING_CAGE3_MDL[] = "models/spring/Cage_3.mdl";
new const SPRING_CAGE4_MDL[] = "models/spring/Cage_4.mdl";
new const SPRING_CAGE5_MDL[] = "models/spring/Cage_5.mdl";

new const SPRING_DIR[] = "spring";
new const SPRING_SAVE[] = "spring_save";
new const SPRING_LOG_DIR[] = "logs/spring";
new const SPRING_CFG[] = {"addons/amxmodx/configs/spring/spring.cfg"};

new const Float:SPRING_MIN[3] = {-14.86, 0.00, -35.88}; //Размеры для пружины (была произведена колибровка)
new const Float:SPRING_MAX[3] = {14.86, 14.83, 35.88}; //Размеры для пружины (была произведена колибровка)
new const Float:SPRING_CAGE1_MIN[3] = {-76.06, -50.92, -76.17}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE1_MAX[3] = {-74.27, 50.42, 400.92}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE2_MIN[3] = {-76.06, -60.00, -76.17}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE2_MAX[3] = {76.27, -58.42, 400.92}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE3_MIN[3] = {-76.06, 35.92, -76.17}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE3_MAX[3] = {76.27, 36.42, 400.92}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE4_MIN[3] = {76.06, -50.92, -76.17}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE4_MAX[3] = {77.27, 50.42, 400.92}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE5_MIN[3] = {-76.06, -58.92, -76.17}; //Размеры для части пружины-клетки (была произведена колибровка)
new const Float:SPRING_CAGE5_MAX[3] = {76.27, 35.28, 5.27}; //Размеры для части пружины-клетки (была произведена колибровка)

//Необходимые переменные, счетчики, массивы и др.:
new SPRING_BUTTON, SPRING_JUMPSPEED_MIN, SPRING_JUMPSPEED_MAX, SPRING_RENDER_AMOUNT, SPRING_TIME_OFFDAMAGE, SPRING_SOUND_CHECK, SPRING_ACCESS_EN;
new SPRING_FIREWORK_EN, SPRING_FIREWORK_NUM, SPRING_FIREWORK_MSG, SPRING_FIREWORK_TIME1, SPRING_FIREWORK_TIME2;
new SPRING_CAGETIME_EN, SPRING_CAGETIME_1, SPRING_CAGETIME_2, SPRING_CAGETIME_3, SPRING_CAGETIME_4, SPRING_CAGETIME_5;
new SPRINGCAGE_OFFDAMAGE, SPRINGCAGE_JUMPSPEED_MIN, SPRINGCAGE_JUMPSPEED_MAX, SPRING_CAGEKILL_EN, SPRING_CAGEKILL_TIME, SPRING_CAGEKILL_INFO, SPRING_MOVE_CVAR;

new g_NoDamage[MAX_PLAYERS+1], g_FireworkCount, g_SpringEnt, g_szLogPath[64];
new bool:g_Player[MAX_PLAYERS+1], g_Time[MAX_PLAYERS+1], g_CheckPlayer;
new Float:g_pOrigin[MAX_PLAYERS+1][3];
new Trie:g_tTrie;

new g_shortSpr[6];
new g_short[6][] =
{
    "sprites/spring/3dmflared.spr",
    "sprites/spring/3dmflaora.spr" ,
    "sprites/spring/frostgib.spr" ,
    "sprites/spring/ledglow.spr" ,
    "sprites/spring/pink.spr" ,
    "sprites/spring/star_gib.spr"
};

public plugin_init()
{
    register_plugin(PLUGIN, VERSION, AUTHOR);

    // Отключаем не нужные карты (на картах, начинающихся на эти префиксы, не будет работать плагин (если не нужно, то '//' строки))
    new mapname[MAX_MAPNAME_LENGTH];
    get_mapname(mapname, charsmax(mapname));
    new maps[][] = { "$", "fy_", "aim_" };
    for(new i; i < sizeof maps; i++){
        if(containi(mapname, maps[i]) != -1){
            pause("ad");
            return;
        }
    }

    register_dictionary("spring.txt");

    RegisterHam(Ham_Use, "func_button", "fwdUse", 0);
    RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage", 0);
    RegisterHamPlayer(Ham_Spawn, "fw_SpawnPlayer", 1);

    register_clcmd("say /sp-menu", "cmdSpringMenu");
    register_clcmd("say /freedom", "cmdFreedom");
    register_clcmd("say /pardon", "cmdPardon");

    g_tTrie = TrieCreate()
    SPRING_BUTTON = engfunc(EngFunc_AllocString, "func_button");

    SPRING_ACCESS_EN = create_cvar("sp_access_en", "1", FCVAR_NONE, "Access spring use", true, 0.0, true, 2.0); //Всем/Админы/Мульти-Флаг - 0/1/2 кому можно использовать.
    SPRING_TIME_OFFDAMAGE = create_cvar("sp_time_offdmg", "5.0", FCVAR_NONE, "Spring time damage off", true, 0.0, true, 32.0); //Время до сброса бессмертия fmt Float.
    SPRINGCAGE_OFFDAMAGE = create_cvar("sp_сage_offdmg", "0", FCVAR_NONE, "Spring cage damage off or on", true, 0.0, true, 1.0); //Убивать в клетке между Т и КТ? (0/1 - выкл/вкл)
    SPRING_JUMPSPEED_MIN = create_cvar("sp_jmspeed_min", "400.0", FCVAR_NONE, "Jump speed min", false, 0.0, false, 0.0); //Мин. скорость прыжка вверх (отскок) fmt Float.
    SPRING_JUMPSPEED_MAX = create_cvar("sp_jmspeed_max", "700.0", FCVAR_NONE, "Jump speed max", false, 0.0, false, 0.0); //Макс. скорость прыжка вверх (отскок) fmt Float.
    SPRINGCAGE_JUMPSPEED_MIN = create_cvar("spcage_jmspeed_min", "200.0", FCVAR_NONE, "Jump speed min cage", false, 0.0, false, 0.0); //Мин. скорость прыжка вверх fmt Float.
    SPRINGCAGE_JUMPSPEED_MAX = create_cvar("spcage_jmspeed_max", "400.0", FCVAR_NONE, "Jump speed max cage", false, 0.0, false, 0.0); //Макс. скорость прыжка вверх fmt Float.
    SPRING_RENDER_AMOUNT = create_cvar("sp_render_amount", "70", FCVAR_NONE, "Render amount model", false, 0.0, false, 0.0); //Яркость свечения оболочки модели (только борд)
    SPRING_FIREWORK_EN = create_cvar("sp_firework_en", "1", FCVAR_NONE, "Firework enabled spring board", true, 0.0, true, 1.0); //Вкл/Выкл - 1/0 запуск феерверка при прыжке на борде.
    SPRING_FIREWORK_NUM = create_cvar("sp_firework_num", "1", FCVAR_NONE, "Firework count", false, 0.0, false, 0.0); //Кол-во раз подряд запуска феерверка при прыжке.
    SPRING_FIREWORK_TIME1 = create_cvar("sp_firework_time1", "0.3", FCVAR_NONE, "Time Fw Hud", true, 0.0, true, 32.0); //время до запуска первого феерверка. fmt Float.
    SPRING_FIREWORK_TIME2 = create_cvar("sp_firework_time2", "0.8", FCVAR_NONE, "Time Fw Hud", true, 0.0, true, 32.0); //время до повторного заряда феерверка fmt Float.
    SPRING_FIREWORK_MSG = create_cvar("sp_firework_msg", "1", FCVAR_NONE, "Firework Message", true, 0.0, true, 1.0); //Одному/Всем - 1/0 видимость феерверка около игрока.
    SPRING_SOUND_CHECK = create_cvar("sp_sound_check", "1", FCVAR_NONE, "Spring sound check", true, 0.0, true, 1.0); //Всем/Одному - 0/1 кому слышна музыка.
    SPRING_CAGETIME_EN = create_cvar("sp_cagetime_en", "1", FCVAR_NONE, "Spring cage time enabled", true, 0.0, true, 1.0); //Вкл/Выкл - 1/0 возможность сажать в клетку на время.
    SPRING_CAGETIME_1 = create_cvar("sp_cagetime_1", "10", FCVAR_NONE, "Spring cage time 1", false, 0.0, false, 0.0); //Время на которое сажать игрока в клетку (мин).
    SPRING_CAGETIME_2 = create_cvar("sp_cagetime_2", "15", FCVAR_NONE, "Spring cage time 2", false, 0.0, false, 0.0); //Время на которое сажать игрока в клетку (мин).
    SPRING_CAGETIME_3 = create_cvar("sp_cagetime_3", "20", FCVAR_NONE, "Spring cage time 3", false, 0.0, false, 0.0); //Время на которое сажать игрока в клетку (мин).
    SPRING_CAGETIME_4 = create_cvar("sp_cagetime_4", "25", FCVAR_NONE, "Spring cage time 4", false, 0.0, false, 0.0); //Время на которое сажать игрока в клетку (мин).
    SPRING_CAGETIME_5 = create_cvar("sp_cagetime_5", "30", FCVAR_NONE, "Spring cage time 5", false, 0.0, false, 0.0); //Время на которое сажать игрока в клетку (мин).
    SPRING_CAGEKILL_EN = create_cvar("sp_cagekill_en", "1", FCVAR_NONE, "Spring cage kill player(s)", true, 0.0, true, 1.0); //Вкл/Выкл - 1/0 убивать игрока(ов) в клетке через время
    SPRING_CAGEKILL_TIME = create_cvar("sp_cagekill_time", "60.0", FCVAR_NONE, "Spring cage kill time", false, 0.0, false, 0.0); //через сколько сек убивать игрока(ов) в клетке
    SPRING_CAGEKILL_INFO = create_cvar("sp_cagekill_info", "1", FCVAR_NONE, "Spring cage kill info)", true, 0.0, true, 1.0); //Вкл/Выкл - 1/0 инфо за 5 сек до смерти игрока в клетке
    SPRING_MOVE_CVAR = create_cvar("sp_move_cvar", "10.0", FCVAR_NONE, "Spring move cvar", false, 0.0, false, 0.0); //значение для функции перемещения (подстановка в коде, дальность)
}

public plugin_cfg()
{
    new paths[64], otherspaths[100];
    spring_get_configsdir(paths, 63);

    if(!dir_exists(paths)){
        mkdir(paths);
    }

    formatex(otherspaths, 99, "%s/%s", paths, SPRING_SAVE);

    if(!dir_exists(otherspaths)){
        mkdir(otherspaths);
    }

    if(file_exists(SPRING_CFG)){
        server_cmd("exec %s", SPRING_CFG);
    }

    new Date[16];
    get_time("%d_%m_%y", Date, charsmax(Date));

    get_localinfo("amxx_basedir", g_szLogPath, charsmax(g_szLogPath));
    new iLen = formatex(g_szLogPath, charsmax(g_szLogPath), "%s/%s",g_szLogPath, SPRING_LOG_DIR);
 
    if(!dir_exists(g_szLogPath)){
        mkdir(g_szLogPath);
    }

    formatex(g_szLogPath[iLen], charsmax(g_szLogPath) - iLen, "/spring-log_%s.txt", Date);

    read_spring();
}

public plugin_precache()
{
    precache_sound(SPRING_SND)

    precache_model(SPRING_MDL)
    precache_model(SPRING_CAGE1_MDL)
    precache_model(SPRING_CAGE2_MDL)
    precache_model(SPRING_CAGE3_MDL)
    precache_model(SPRING_CAGE4_MDL)
    precache_model(SPRING_CAGE5_MDL)

    for(new i; i < sizeof g_short; i++){
        g_shortSpr[i] = precache_model(g_short[i]);
    }
}

public client_authorized(iPlayer, const szAuthID[]) //Получаем данные если игрок зашел
{
    if(TrieGetCell(g_tTrie, szAuthID, g_Time[iPlayer])){
        TrieDeleteKey(g_tTrie, szAuthID)
    }
}

public client_disconnected(iPlayer) //Сохраняем данные если игрок вышел
{
    if(g_Player[iPlayer] == true || g_Time[iPlayer] == -1 || g_Time[iPlayer] > 1){
        new szAuthID[MAX_AUTHID_LENGTH];

        get_user_authid(iPlayer, szAuthID, charsmax(szAuthID))
        TrieSetCell(g_tTrie, szAuthID, g_Time[iPlayer])

        g_Time[iPlayer] = 0;
        g_Player[iPlayer] = false;
    }
}

public fw_SpawnPlayer(iPlayer) //Событие spawn действует для тех, у кого по условиям проходит.
{
    if(!is_user_alive(iPlayer)) return HAM_IGNORED;

    if(g_Player[iPlayer] == true || g_Time[iPlayer] == -1 || g_Time[iPlayer] > 1){
        if(get_pcvar_num(SPRING_CAGETIME_EN) == 1){
            if(g_Time[iPlayer] < 1){
                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_FREEDOM1");
                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_FREEDOM2");

                fm_set_user_godmode(iPlayer, 0);
                g_Player[iPlayer] = false;
                g_Time[iPlayer] = 0;

                return HAM_IGNORED;
            }
            else{
                new Min = g_Time[iPlayer] - time();

                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_TIMECHECK", Min / 60);
                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_PARDONINFO");
            }
        }

        //спавн в клетку
        new Float:v_Origin[3], ent;

        while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "T-Cage_spring"))){
            pev(ent, pev_origin, v_Origin)
        }

        ent = 0;
        v_Origin[2] += 60;

        set_pev(iPlayer, pev_velocity, Float:{0.0, 0.0, 0.0})
        set_pev(iPlayer, pev_origin, v_Origin)

        if(get_pcvar_num(SPRINGCAGE_OFFDAMAGE) == 0){
            fm_set_user_godmode(iPlayer, 1);
        }

        //Убиваем тех кто в клетке через время (дабы избежать такого, что в клетке кто-то есть, а раунд все идет и подобных случаев)
        if(get_pcvar_num(SPRING_CAGEKILL_EN) == 1){
            if(get_pcvar_num(SPRING_CAGEKILL_INFO) == 1){
                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_KILLINFO", iPlayer, get_pcvar_num(SPRING_CAGEKILL_TIME));
            }
            remove_task(iPlayer);
            set_task(get_pcvar_float(SPRING_CAGEKILL_TIME), "Spring_Cage_Kill_Eff1", iPlayer);
        }

        //Инфа по поводу возможности не поподать в клетку впринципе (как получить иммунитет)
        client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_IMMUNINFO");
    }

    return HAM_IGNORED;
}

public Spring_Cage_Kill_Eff1(iPlayer) //эффект при убийстве игроков в клетке / часть 1.
{
    new Float:velocity1[3];

    entity_get_vector(iPlayer,EV_VEC_velocity,velocity1)
    velocity1[2] += 1000;
    entity_set_vector(iPlayer,EV_VEC_velocity,velocity1)

    set_task(0.5, "Spring_Cage_Kill_Eff2", iPlayer);
}

public Spring_Cage_Kill_Eff2(iPlayer) //эффект при убийстве игроков в клетке / часть 2.
{
    new Float:velocity2[3];

    entity_get_vector(iPlayer,EV_VEC_velocity,velocity2)
    velocity2[2] -= 1000;
    entity_set_vector(iPlayer,EV_VEC_velocity,velocity2)

    set_task(1.0, "Spring_Cage_Kill_Eff3", iPlayer);
}

public Spring_Cage_Kill_Eff3(iPlayer) //эффект при убийстве игроков в клетке / часть 3.
{
    new Float:velocity3[3];

    entity_get_vector(iPlayer,EV_VEC_velocity,velocity3)
    velocity3[2] += 1000;
    entity_set_vector(iPlayer,EV_VEC_velocity,velocity3)

    set_task(0.5, "Spring_Cage_Kill_Eff4", iPlayer);
}

public Spring_Cage_Kill_Eff4(iPlayer) //эффект при убийстве игроков в клетке / часть 4.
{
    new Float:velocity4[3];

    entity_get_vector(iPlayer,EV_VEC_velocity,velocity4)
    velocity4[2] -= 1000;
    entity_set_vector(iPlayer,EV_VEC_velocity,velocity4)

    set_task(3.0, "Spring_Cage_Kill", iPlayer);
}

public Spring_Cage_Kill(iPlayer) //Функция смерти игроков которые в клетке / часть 5.
{
    fm_set_user_godmode(iPlayer, 0); //если стояло бессмертие убираем для килла.
    user_silentkill(iPlayer); //убиваем, что никто не увидет сообщения об этом, в верхнем правом углу.
}

public cmdFreedom(iPlayer) //узнать сколько осталось сидеть в клетке по команде
{
    if(!is_user_alive(iPlayer)) return PLUGIN_HANDLED;

    if(g_Player[iPlayer] == true || g_Time[iPlayer] == -1 || g_Time[iPlayer] > 1){
        if(get_pcvar_num(SPRING_CAGETIME_EN) == 1){
            if(g_Time[iPlayer] > 1){
                new Min = g_Time[iPlayer] - time();

                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_TIMECHECK", Min / 60);
                client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_PARDONINFO");
            }
        }
    }

    return PLUGIN_HANDLED;
}

public cmdPardon(iPlayer) //Игрок из клетки просит кого-то из админов его высунуть (прощения)
{
    if(!is_user_alive(iPlayer)) return PLUGIN_HANDLED;

    if(g_Player[iPlayer] == true || g_Time[iPlayer] == -1 || g_Time[iPlayer] > 1){
        new iPlayersID[MAX_PLAYERS], iPlayerNum, iCheckAdmin;
        get_players_ex(iPlayersID, iPlayerNum, GetPlayers_ExcludeDead|GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

        for(new i; i < iPlayerNum; i++){
            if(get_user_flags(iPlayersID[i]) & ACCESS_ADMIN_FLAG){
                client_print_color(iPlayersID[i], print_team_default, "%l", "SPRING_CAGE_PARDON1", iPlayersID[i], iPlayer);
                client_print_color(iPlayersID[i], print_team_default, "%l", "SPRING_CAGE_PARDON2");

                iCheckAdmin = 1;
            }
        }

        if(iCheckAdmin == 1){
            client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_PARDON3", iPlayer);
            iCheckAdmin = 0;
        }
        else{
            client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_PARDON4", iPlayer);
        }

        log_to_file(g_szLogPath, "%L", LANG_PLAYER, "SPRING_MULTI_LOG1", iPlayer);
    }

    return PLUGIN_HANDLED;
}

public read_spring() //Расстановка уже сохраненных точек на карте.
{
    new mapname[MAX_MAPNAME_LENGTH], springfile[128];
    get_mapname(mapname, MAX_MAPNAME_LENGTH-1);

    spring_get_configsdir(springfile, 127);
    formatex(springfile, 127, "%s/%s/%s.cfg", springfile, SPRING_SAVE, mapname);

    if(!file_exists(springfile)){
        return;
    }

    new szData[41];
    new szType[1], szX[13], szY[13], szZ[13];
    new Float:vOrigin[3];
    new f = fopen(springfile, "rt");

    while(!feof(f)){
        fgets(f, szData, 40)
        parse(szData, szType, 1, szX, 12, szY, 12, szZ, 12)

        vOrigin[0] = str_to_float(szX)
        vOrigin[1] = str_to_float(szY)
        vOrigin[2] = str_to_float(szZ)

        if(szType[0] == 'S'){
            makeBox(0, 1, "Spring", vOrigin)
        }
        else if(szType[0] == 'Q'){
            makeBox(0, 2, "Q-Cage_spring", vOrigin)
        }
        else if(szType[0] == 'W'){
            makeBox(0, 3, "W-Cage_spring", vOrigin)
        }
        else if(szType[0] == 'E'){
            makeBox(0, 4, "E-Cage_spring", vOrigin)
        }
        else if(szType[0] == 'R'){
            makeBox(0, 5, "R-Cage_spring", vOrigin)
        }
        else if(szType[0] == 'T'){
            makeBox(0, 6, "T-Cage_spring", vOrigin)
        }
        else{
            log_to_file(g_szLogPath, "%L", LANG_PLAYER, "SPRING_MULTI_LOG2", springfile);
            fclose(f);
            return;
        }
    }

    fclose(f);
    log_to_file(g_szLogPath, "%L", LANG_PLAYER, "SPRING_MULTI_LOG3", springfile);
}

public fwdUse(ent, id) //Отлов события нажатия клавиши "E" на клавиатуре в игре, ('E' == use)
{
    if(!ent || id > 32){
        return FMRES_IGNORED;
    }

    if(!is_user_alive(id)){
        return FMRES_IGNORED;
    }

    //Настройка использования (кому можно использовать):
    new g_UserFlags = get_user_flags(id);

    if(get_pcvar_num(SPRING_ACCESS_EN) == 0){
        Action_Jump_Spring(id);
        return FMRES_IGNORED;
    }
    else if(get_pcvar_num(SPRING_ACCESS_EN) == 1 && g_UserFlags & ACCESS_ADMIN_FLAG){
        Action_Jump_Spring(id);
        return FMRES_IGNORED;
    }
    else if(get_pcvar_num(SPRING_ACCESS_EN) == 2 && g_UserFlags & ACCESS_MULTI_FLAG){
        Action_Jump_Spring(id);
        return FMRES_IGNORED;
    }

    //Выводим сообщения об ограниченном доступе если это обычный игрок:
    if(get_pcvar_num(SPRING_ACCESS_EN) == 2 && g_UserFlags & ADMIN_USER){
        client_print_color(id, print_team_default, "%l", "SPRING_ACCESS_ERR2");
    }
    else if(get_pcvar_num(SPRING_ACCESS_EN) == 1 && g_UserFlags & (ACCESS_VIP_FLAG|ADMIN_USER)){
        client_print_color(id, print_team_default, "%l", "SPRING_ACCESS_ERR1");
    }

    return FMRES_IGNORED;
}

public Action_Jump_Spring(id) //функция для подстановки события прыжка и тп
{
    //Даем звук пружины
    emit_sound(get_pcvar_num(SPRING_SOUND_CHECK) == 1 ? id : 0, CHAN_AUTO, SPRING_SND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

    //Отскок от пружины
    new Float:velocity[3];
    entity_get_vector(id,EV_VEC_velocity,velocity)

    if(g_Player[id] == true || g_Time[id] == -1 || g_Time[id] > 1){
        velocity[2] = random_float(get_pcvar_float(SPRINGCAGE_JUMPSPEED_MIN),get_pcvar_float(SPRINGCAGE_JUMPSPEED_MAX))
    }
    else{
        velocity[2] = random_float(get_pcvar_float(SPRING_JUMPSPEED_MIN),get_pcvar_float(SPRING_JUMPSPEED_MAX))
    }

    entity_set_vector(id,EV_VEC_velocity,velocity)

    //Задаем значение переменной (для проверки в fw_TakeDamage)
    g_NoDamage[id] = id;
    //Kill процесс если быстро нажали еще раз (прыгают несколько раз подряд и более..)
    remove_task(id);
    //Отрубаем бессмертие путем сброса значения массива g_NoDamage
    set_task(get_pcvar_float(SPRING_TIME_OFFDAMAGE), "NoDamage_Off", id);

    //Даем феерверк при прыжке
    if(get_pcvar_num(SPRING_FIREWORK_EN) == 1){
        set_task(get_pcvar_float(SPRING_FIREWORK_TIME1), "firework_spring", id);
    }
}

public fw_TakeDamage(victim, inflictor, attacker, Float:damage)
{
    if(victim == g_NoDamage[victim] && is_user_alive(victim)){
        SetHamParamFloat(4, damage - damage)
        return HAM_HANDLED;
    }

    return HAM_IGNORED;
}

public NoDamage_Off(id)
{
    g_NoDamage[id] = 0;
}

public cmdSpringMenu(id)
{
    if(get_user_flags(id) & ACCESS_ADMIN_FLAG){
        spring_makemenu(id);
    }
}

public firework_spring(id)
{
    for(new j; j < sizeof g_shortSpr; j++)
    {
        new origin[3];
        get_user_origin(id,origin,0)

        message_begin(get_pcvar_num(SPRING_FIREWORK_MSG) == 1 ? MSG_ONE : MSG_ALL,SVC_TEMPENTITY,{0,0,0},id)

        write_byte(TE_SPRITETRAIL)
        write_coord(origin[0]-random_num(6,10))
        write_coord(origin[1]-random_num(7,15))
        write_coord(origin[2]+random_num(30,70))
        write_coord(origin[0]-random_num(5,9))
        write_coord(origin[1]-random_num(9,20))
        write_coord(origin[2]+random_num(50,100))
        write_short(g_shortSpr[j]);
        write_byte(random_num(2,7))
        write_byte(random_num(7,15))
        write_byte(random_num(3,6))
        write_byte(random_num(6,20))
        write_byte(random_num(20,50))
        message_end()
    }

    if(get_pcvar_num(SPRING_FIREWORK_NUM) == 1){
        return PLUGIN_HANDLED;
    }
    else if(g_FireworkCount <= get_pcvar_num(SPRING_FIREWORK_NUM)){
        g_FireworkCount++;
        set_task(get_pcvar_float(SPRING_FIREWORK_TIME2), "firework_spring", id)
    }
    else if(g_FireworkCount > get_pcvar_num(SPRING_FIREWORK_NUM)){
        g_FireworkCount = 0
    }
    return PLUGIN_HANDLED;
}


//Далее менюшки и все что с ними связано-завязано :)

public spring_makemenu(id) //главное меню пружины
{
    if(!is_user_connected(id)) return;

    new g_SpringMenu[64];

    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_TITLE");
    new menu = menu_create(g_SpringMenu, "springmenufunc");
    new callback = menu_makecallback("ignormenufunc_2");

    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM1");
    menu_additem(menu, g_SpringMenu, "1", .callback = callback);
    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM2");
    menu_additem(menu, g_SpringMenu, "2", .callback = callback);
    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM3");
    menu_additem(menu, g_SpringMenu, "3", .callback = callback);
    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM4");
    menu_additem(menu, g_SpringMenu, "4", .callback = callback);
    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM5");
    menu_additem(menu, g_SpringMenu, "5", .callback = callback);
    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM6");
    menu_additem(menu, g_SpringMenu, "6", 0);
    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_ITEM7");
    menu_additem(menu, g_SpringMenu, "7", 0);

    formatex(g_SpringMenu, 63, "%L", id, "SPRING_MENU_EXIT");
    menu_setprop(menu, MPROP_EXITNAME, g_SpringMenu);

    menu_display(id, menu);
}

public springmenufunc(id, menu, item) //внутринности для главного меню
{
    if(item == MENU_EXIT){
        menu_destroy(menu);
        return PLUGIN_HANDLED;
    }

    new data[6], iName[64];
    new iaccess, callback;

    menu_item_getinfo(menu, item, iaccess, data, 5, iName, 63, callback);
    menu_destroy(menu);

    new key = str_to_num(data);

    switch(key)
    {
        case 1: //создание
            {
                spring_checkmenu(id);
                return PLUGIN_HANDLED;
            }
        case 2: //перемещение
            {
                spring_movemenu(id);
                return PLUGIN_HANDLED;
            }
        case 3: //удаление одной пружины
            {
                new ent, body;
                get_user_aiming(id, ent, body, 9999);

                //проверяем на валидность объекта!
                if(!pev_valid(ent)){
                    client_print_color(id, print_team_default, "%l", "SPRING_OBJECT_ERR");
                }
                else{
                    new szClassname[33];

                    pev(ent, pev_classname, szClassname, 32);
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)

                    client_print_color(id, print_team_default, "%l", "SPRING_DEL_ONE");
                }
            }
        case 4: //удаление всех пружин на карте
            {
                new ent;

                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "Spring"))){
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)
                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "Q-Cage_spring"))){
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)
                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "W-Cage_spring"))){
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)
                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "E-Cage_spring"))){
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)
                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "R-Cage_spring"))){
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)
                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "T-Cage_spring"))){
                    set_pev(ent, pev_flags, pev(ent, pev_flags) | FL_KILLME)
                    g_SpringEnt = ent
                }

                if(g_SpringEnt == 0){
                    client_print_color(id, print_team_default, "%l", "SPRING_DEL_ERROR");
                    ent = 0
                    g_SpringEnt = 0
                }
                else{
                    client_print_color(id, print_team_default, "%l", "SPRING_DEL_ALL");
                    ent = 0
                    g_SpringEnt = 0
                }
            }
        case 5: //сохранение точек пружин на карте (для последуещего воспроизведения (расстановки))
            {
                new mapname[MAX_MAPNAME_LENGTH], springfile[128];
                get_mapname(mapname, MAX_MAPNAME_LENGTH-1);

                spring_get_configsdir(springfile, 127);
                formatex(springfile, 127, "%s/%s/%s.cfg", springfile, SPRING_SAVE, mapname)

                if(file_exists(springfile)){
                    delete_file(springfile);
                }

                new ent, Float:vOrigin[3], szData[42];
                new f = fopen(springfile, "at");

                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "Spring"))){
                    pev(ent, pev_origin, vOrigin)
                    formatex(szData, 41, "S %f %f %f^n", vOrigin[0], vOrigin[1], vOrigin[2])
                    fputs(f, szData)

                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "Q-Cage_spring"))){
                    pev(ent, pev_origin, vOrigin)
                    formatex(szData, 41, "Q %f %f %f^n", vOrigin[0], vOrigin[1], vOrigin[2])
                    fputs(f, szData)

                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "W-Cage_spring"))){
                    pev(ent, pev_origin, vOrigin)
                    formatex(szData, 41, "W %f %f %f^n", vOrigin[0], vOrigin[1], vOrigin[2])
                    fputs(f, szData)

                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "E-Cage_spring"))){
                    pev(ent, pev_origin, vOrigin)
                    formatex(szData, 41, "E %f %f %f^n", vOrigin[0], vOrigin[1], vOrigin[2])
                    fputs(f, szData)

                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "R-Cage_spring"))){
                    pev(ent, pev_origin, vOrigin)
                    formatex(szData, 41, "R %f %f %f^n", vOrigin[0], vOrigin[1], vOrigin[2])
                    fputs(f, szData)

                    g_SpringEnt = ent
                }
                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "T-Cage_spring"))){
                    pev(ent, pev_origin, vOrigin)
                    formatex(szData, 41, "T %f %f %f^n", vOrigin[0], vOrigin[1], vOrigin[2])
                    fputs(f, szData)

                    g_SpringEnt = ent
                }

                if(g_SpringEnt == 0){
                    client_print_color(id, print_team_default, "%l", "SPRING_SAVE_ERROR");
                    ent = 0
                    g_SpringEnt = 0
                }
                else{
                    client_print_color(id, print_team_default, "%l", "SPRING_SAVE_ACTION");
                    ent = 0
                    g_SpringEnt = 0
                }

                fclose(f);
            }
        case 6: //меню перемещения игрока в клетку
            {
                new Float:p_Origin[3], ent;

                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "T-Cage_spring"))){
                    pev(ent, pev_origin, p_Origin)
                }

                ent = 0;
                p_Origin[2] += 60;
                g_pOrigin[id] = p_Origin; //тп игрока через меню

                spring_playermenu(id);
                return PLUGIN_HANDLED;
            }
        case 7: //меню досрочного освобождения из клетки
            {
                spring_menufreedom(id);
                return PLUGIN_HANDLED;
            }
    }

    spring_makemenu(id);
    return PLUGIN_HANDLED;
}

public spring_menufreedom(id) //меню выбора игроков для досрочного освобождения
{
    if(!is_user_connected(id)) return;

    new g_SpringMenuFreedom[64];

    formatex(g_SpringMenuFreedom, 63, "%L", id, "SPRING_MENUFREEDOM_TITLE");
    new menu = menu_create(g_SpringMenuFreedom, "springfreedomfunc");
    new callback = menu_makecallback("ignormenufunc_3");

    new szName[MAX_NAME_LENGTH], szInfo[3], iPlayers[MAX_PLAYERS], iPlayer, iNum;
    get_players_ex(iPlayers, iNum, GetPlayers_ExcludeDead|GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new i; i < iNum; i++){
        iPlayer = iPlayers[i];
        szInfo[0] = iPlayer;

        get_user_name(iPlayer, szName, charsmax(szName));
        menu_additem(menu, szName, szInfo, .callback = callback);
    }

    formatex(g_SpringMenuFreedom, 63, "%L", id, "SPRING_MENU_BACK");
    menu_setprop(menu, MPROP_BACKNAME, g_SpringMenuFreedom);
    formatex(g_SpringMenuFreedom, 63, "%L", id, "SPRING_MENU_NEXT");
    menu_setprop(menu, MPROP_NEXTNAME, g_SpringMenuFreedom);
    formatex(g_SpringMenuFreedom, 63, "%L", id, "SPRING_MENU_EXIT");
    menu_setprop(menu, MPROP_EXITNAME, g_SpringMenuFreedom);

    menu_display(id, menu);
}

public springfreedomfunc(id, menu, item) //внутринности для меню досрочного освобождения из клетки
{
    if(item == MENU_EXIT){
        menu_destroy(menu);
        spring_makemenu(id);
        return PLUGIN_HANDLED;
    }

    new szInfo[3], buffer;

    menu_item_getinfo(menu, item, buffer, szInfo, charsmax(szInfo), .callback = buffer);
    menu_destroy(menu);

    new iPlayer = szInfo[0];
    Freedom_Player(id, iPlayer);

    return PLUGIN_HANDLED;
}

public Freedom_Player(id, iPlayer) //отпускаем игрока
{
    g_Player[iPlayer] = false;
    g_Time[iPlayer] = 0;

    client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_FREEDOM3", iPlayer, id);
    client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_FREEDOM2");
    client_print_color(id, print_team_default, "%l", "SPRING_CAGE_FREEDOMADMIN", iPlayer);

    log_to_file(g_szLogPath, "%L", LANG_PLAYER, "SPRING_MULTI_LOG4", id, iPlayer);
    spring_menufreedom(id);
}

public spring_checkmenu(id) //выбор пружины или клетки-пружины
{
    if(!is_user_connected(id)) return;

    new g_SpringCheckMenu[64];

    formatex(g_SpringCheckMenu, 63, "%L", id, "SPRING_CHECKMENU_TITLE");
    new menu = menu_create(g_SpringCheckMenu, "springcheckfunc");

    formatex(g_SpringCheckMenu, 63, "%L", id, "SPRING_CHECKMENU_ITEM1");
    menu_additem(menu, g_SpringCheckMenu, "1", 0);
    formatex(g_SpringCheckMenu, 63, "%L", id, "SPRING_CHECKMENU_ITEM2");
    menu_additem(menu, g_SpringCheckMenu, "2", 0);

    formatex(g_SpringCheckMenu, 63, "%L", id, "SPRING_MENU_BACK");
    menu_setprop(menu, MPROP_EXITNAME, g_SpringCheckMenu);

    menu_display(id, menu);
}

public springcheckfunc(id, menu, item) //внутринности для меню выбора клетки или пружины
{
    if(item == MENU_EXIT){
        menu_destroy(menu);
        spring_makemenu(id);
        return PLUGIN_HANDLED;
    }

    new data[6], iName[64];
    new iaccess, callback;

    menu_item_getinfo(menu, item, iaccess, data, 5, iName, 63, callback);
    menu_destroy(menu);

    new key = str_to_num(data);

    switch(key)
    {
        case 1: //создание пружина борда
            {
                makeBox(id, 1, "Spring");
                client_print_color(id, print_team_default, "%l", "SPRING_CREATED");
            }
        case 2: //создание из частей клетки пружины
            {
                new ent, check;

                while((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "Q-Cage_spring"))){
                    check = ent;
                }

                if(check != 0){
                    client_print_color(id, print_team_default, "%l", "SPRING_CAGE_CHECK");
                    ent = 0;
                    check = 0;
                    return PLUGIN_HANDLED;
                }

                makeBox(id, 2, "Q-Cage_spring");
                makeBox(id, 3, "W-Cage_spring");
                makeBox(id, 4, "E-Cage_spring");
                makeBox(id, 5, "R-Cage_spring");
                makeBox(id, 6, "T-Cage_spring");
                client_print_color(id, print_team_default, "%l", "SPRING_CAGE_CREATED");
            }
    }

    spring_checkmenu(id);
    return PLUGIN_HANDLED;
}

public spring_movemenu(id) //меню настроек (перемещение)
{
    if(!is_user_connected(id)) return;

    new g_SpringMoveMenu[64];

    formatex(g_SpringMoveMenu, 63, "%L", id, "SPRING_MOVEMENU_TITLE");
    new menu = menu_create(g_SpringMoveMenu, "springmovefunc");

    menu_additem(menu, "X++", "1", 0);
    menu_additem(menu, "X--", "2", 0);
    menu_additem(menu, "Y++", "3", 0);
    menu_additem(menu, "Y--", "4", 0);
    menu_additem(menu, "Z++", "5", 0);
    menu_additem(menu, "Z--", "6", 0);

    formatex(g_SpringMoveMenu, 63, "%L", id, "SPRING_MENU_BACK");
    menu_setprop(menu, MPROP_EXITNAME, g_SpringMoveMenu);

    menu_display(id, menu);
}

public springmovefunc(id, menu, item) //внутринности для меню перемещения
{
    if(item == MENU_EXIT){
        menu_destroy(menu);
        spring_makemenu(id);
        return PLUGIN_HANDLED;
    }

    new data[6], iName[64];
    new iaccess, callback;

    menu_item_getinfo(menu, item, iaccess, data, 5, iName, 63, callback);
    menu_destroy(menu);

    moveBox(id, str_to_num(data));

    spring_movemenu(id);
    return PLUGIN_HANDLED;
}

public spring_playermenu(id) //меню выбора игрока для перемещения в клетку
{
    if(!is_user_connected(id)) return;

    new g_SpringPlayerMenu[64];

    formatex(g_SpringPlayerMenu, 63, "%L", id, "SPRING_PLAYERMENU_TITLE");

    new menu = menu_create(g_SpringPlayerMenu, "springplayerfunc");
    new callback = menu_makecallback("ignormenufunc_1");

    new szName[MAX_NAME_LENGTH], szInfo[3], iPlayers[MAX_PLAYERS], iPlayer, iNum;
    get_players_ex(iPlayers, iNum, GetPlayers_ExcludeDead|GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new i; i < iNum; i++){
        iPlayer = iPlayers[i];
        szInfo[0] = iPlayer;

        get_user_name(iPlayer, szName, charsmax(szName));
        menu_additem(menu, szName, szInfo, .callback = callback);
    }

    formatex(g_SpringPlayerMenu, 63, "%L", id, "SPRING_MENU_BACK");
    menu_setprop(menu, MPROP_BACKNAME, g_SpringPlayerMenu);
    formatex(g_SpringPlayerMenu, 63, "%L", id, "SPRING_MENU_NEXT");
    menu_setprop(menu, MPROP_NEXTNAME, g_SpringPlayerMenu);
    formatex(g_SpringPlayerMenu, 63, "%L", id, "SPRING_MENU_EXIT");
    menu_setprop(menu, MPROP_EXITNAME, g_SpringPlayerMenu);

    menu_display(id, menu);
}

public springplayerfunc(id, menu, item) //внутринности для меню перемещения игрока в клетку
{
    if(item == MENU_EXIT){
        menu_destroy(menu);
        spring_makemenu(id);
        return PLUGIN_HANDLED;
    }

    new szInfo[3], buffer;

    menu_item_getinfo(menu, item, buffer, szInfo, charsmax(szInfo), .callback = buffer);
    menu_destroy(menu);

    new iPlayer = szInfo[0];

    if(get_pcvar_num(SPRING_CAGETIME_EN) == 1){
        g_CheckPlayer = iPlayer;
        spring_timemenu(id);
    }
    else{
        g_Time[iPlayer] = -1;
        Teleport_Player(id, iPlayer);
    }

    return PLUGIN_HANDLED;
}

public spring_timemenu(id) //меню выбора времени для перемещения игрока в клетку на время
{
    if(!is_user_connected(id)) return;

    new g_SpringTimeMenu[64];

    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_TIMEMENU_TITLE");

    new menu = menu_create(g_SpringTimeMenu, "springtimefunc");

    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_TIMECAGE_1", get_pcvar_num(SPRING_CAGETIME_1));
    menu_additem(menu, g_SpringTimeMenu, "1", 0);
    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_TIMECAGE_2", get_pcvar_num(SPRING_CAGETIME_2));
    menu_additem(menu, g_SpringTimeMenu, "2", 0);
    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_TIMECAGE_3", get_pcvar_num(SPRING_CAGETIME_3));
    menu_additem(menu, g_SpringTimeMenu, "3", 0);
    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_TIMECAGE_4", get_pcvar_num(SPRING_CAGETIME_4));
    menu_additem(menu, g_SpringTimeMenu, "4", 0);
    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_TIMECAGE_5", get_pcvar_num(SPRING_CAGETIME_5));
    menu_additem(menu, g_SpringTimeMenu, "5", 0);

    formatex(g_SpringTimeMenu, 63, "%L", id, "SPRING_MENU_BACK");
    menu_setprop(menu, MPROP_BACKNAME, g_SpringTimeMenu);

    menu_display(id, menu);
}

public springtimefunc(id, menu, item) //внутринности для меню выбора времени на которое перемещается игрок
{
    if(item == MENU_EXIT){
        menu_destroy(menu);
        return PLUGIN_HANDLED;
    }

    new data[6], iName[64];
    new iaccess, callback;

    menu_item_getinfo(menu, item, iaccess, data, 5, iName, 63, callback);
    menu_destroy(menu);

    new key = str_to_num(data);

    switch(key)
    {
        case 1: g_Time[g_CheckPlayer] = time() + get_pcvar_num(SPRING_CAGETIME_1) * 60; //время трансформируемое в минуты 1
        case 2: g_Time[g_CheckPlayer] = time() + get_pcvar_num(SPRING_CAGETIME_2) * 60; //время трансформируемое в минуты 2
        case 3: g_Time[g_CheckPlayer] = time() + get_pcvar_num(SPRING_CAGETIME_3) * 60; //время трансформируемое в минуты 3
        case 4: g_Time[g_CheckPlayer] = time() + get_pcvar_num(SPRING_CAGETIME_4) * 60; //время трансформируемое в минуты 4
        case 5: g_Time[g_CheckPlayer] = time() + get_pcvar_num(SPRING_CAGETIME_5) * 60; //время трансформируемое в минуты 5
    }

    Teleport_Player(id, g_CheckPlayer);
    return PLUGIN_HANDLED;
}

public Teleport_Player(id, iPlayer) //Телепорт в клетку
{
    set_pev(iPlayer, pev_velocity, Float:{0.0, 0.0, 0.0})
    set_pev(iPlayer, pev_origin, g_pOrigin[id])

    g_Player[iPlayer] = true;

    new iPlayers[MAX_PLAYERS], iPlayerCount;
    get_players_ex(iPlayers, iPlayerCount, GetPlayers_ExcludeDead|GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

    for(new i; i < iPlayerCount; i++){
        if(iPlayers[i] != iPlayer) client_print_color(iPlayers[i], print_team_default, "%l", "SPRING_CAGE_INFOALL", iPlayer, id);
    }

    client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_INFOPUNISHMENT1", iPlayer, id);
    client_print_color(iPlayer, print_team_default, "%l", "SPRING_CAGE_INFOPUNISHMENT2");

    if(get_pcvar_num(SPRING_CAGETIME_EN) == 1){
        new Min = g_Time[iPlayer] - time();
        log_to_file(g_szLogPath, "%L", LANG_PLAYER, "SPRING_MULTI_LOG5", id, iPlayer, Min / 60);
    }
    else{
        log_to_file(g_szLogPath, "%L", LANG_PLAYER, "SPRING_MULTI_LOG6", id, iPlayer);
    }

    spring_playermenu(id);
}

public ignormenufunc_1(id, menu, item) //игнорим кого уже переместили или у игрока флаг иммуна (для меню перемещения) или мертв
{
    new szInfo[3], buffer;
    menu_item_getinfo(menu, item, buffer, szInfo, charsmax(szInfo), .callback = buffer);

    new iPlayer = szInfo[0];

    if(!is_user_alive(iPlayer)) return ITEM_DISABLED;
    if(g_Player[iPlayer] == true || g_Time[iPlayer] == -1 || g_Time[iPlayer] > 1 || get_user_flags(iPlayer) & ACCESS_CAGE_FLAG) return ITEM_DISABLED;

    return ITEM_IGNORE;
}

public ignormenufunc_2(id, menu, item) //игнорим основные настройки от обычных админов
{
    if(get_user_flags(id) & (ACCESS_ADMIN_FLAG|ACCESS_MENU_FLAG) == (ACCESS_ADMIN_FLAG|ACCESS_MENU_FLAG)){
        return ITEM_IGNORE;
    }
    else if(get_user_flags(id) & ACCESS_ADMIN_FLAG){
        return ITEM_DISABLED;
    }

    return ITEM_IGNORE;
}

public ignormenufunc_3(id, menu, item) //игнорим игроков которые не в клетке (меню досрочное освобождение) и с иммуном
{
    new szInfo[3], buffer;
    menu_item_getinfo(menu, item, buffer, szInfo, charsmax(szInfo), .callback = buffer);

    new iPlayer = szInfo[0];

    if(get_user_flags(iPlayer) & ACCESS_CAGE_FLAG){
        return ITEM_DISABLED;
    }
    else if(g_Player[iPlayer] == true || g_Time[iPlayer] == -1 || g_Time[iPlayer] > 1){
        return ITEM_IGNORE;
    }

    return ITEM_IGNORE;
}

public spring_get_configsdir(name[], len) //проверка на директории
{
    new g_Dir[64];
    get_localinfo("amxx_configsdir", g_Dir, 63)

    return formatex(name, len, "%s/%s", g_Dir, SPRING_DIR)
}


//Далее главные-системные функции (создание, перемещение и тп):

stock makeBox(id, num, const szClassname[], Float:pOrigin[3]={0.0, 0.0, 0.0})
{
    new ent = engfunc(EngFunc_CreateNamedEntity, SPRING_BUTTON);

    //проверяем на валидность объекта!
    if(!pev_valid(ent)){
        client_print_color(id, print_team_default, "%l", "SPRING_OBJECT_ERR")
        return PLUGIN_HANDLED;
    }

    set_pev(ent, pev_classname, szClassname)
    set_pev(ent, pev_solid, SOLID_BBOX)
    set_pev(ent, pev_movetype, MOVETYPE_NONE)
    set_pev(ent, pev_target)

    switch(num)
    {
        case 1:
            {
                engfunc(EngFunc_SetModel, ent, SPRING_MDL)
                engfunc(EngFunc_SetSize, ent, SPRING_MIN, SPRING_MAX)

                fm_set_rendering(ent, kRenderFxGlowShell, random_num(10,255), random_num(10,255), random_num(10,255), kRenderNormal, get_pcvar_num(SPRING_RENDER_AMOUNT))
            }
        case 2:
            {
                engfunc(EngFunc_SetModel, ent, SPRING_CAGE1_MDL)
                engfunc(EngFunc_SetSize, ent, SPRING_CAGE1_MIN, SPRING_CAGE1_MAX)
            }
        case 3:
            {
                engfunc(EngFunc_SetModel, ent, SPRING_CAGE2_MDL)
                engfunc(EngFunc_SetSize, ent, SPRING_CAGE2_MIN, SPRING_CAGE2_MAX)
            }
        case 4:
            {
                engfunc(EngFunc_SetModel, ent, SPRING_CAGE3_MDL)
                engfunc(EngFunc_SetSize, ent, SPRING_CAGE3_MIN, SPRING_CAGE3_MAX)
            }
        case 5:
            {
                engfunc(EngFunc_SetModel, ent, SPRING_CAGE4_MDL)
                engfunc(EngFunc_SetSize, ent, SPRING_CAGE4_MIN, SPRING_CAGE4_MAX)
            }
        case 6:
            {
                engfunc(EngFunc_SetModel, ent, SPRING_CAGE5_MDL)
                engfunc(EngFunc_SetSize, ent, SPRING_CAGE5_MIN, SPRING_CAGE5_MAX)
            }
    }

    if(id){ //ставит игрок
        new Float:vOrigin[3];
        fm_get_aim_origin(id, vOrigin)
        vOrigin[2] += 22.0 //положить на пол
        engfunc(EngFunc_SetOrigin, ent, vOrigin);
    }
    else{ //ставит функция read_spring
        engfunc(EngFunc_SetOrigin, ent, pOrigin)
    }

    return PLUGIN_HANDLED;
}

stock moveBox(id, mode) //перемещение пружины
{
    new ent, body, szClassname[33];
    get_user_aiming(id, ent, body, 9999);

    //проверяем на валидность объекта!
    if(!pev_valid(ent)){
        client_print_color(id, print_team_default, "%l", "SPRING_MOVE_ERR");
        return PLUGIN_HANDLED;
    }

    pev(ent, pev_classname, szClassname, 32);

    new Float:vOrigin[3];
    pev(ent, pev_origin, vOrigin);

    switch(mode)
    {
        case 1: vOrigin[0] += get_pcvar_float(SPRING_MOVE_CVAR);
        case 2: vOrigin[0] -= get_pcvar_float(SPRING_MOVE_CVAR);
        case 3: vOrigin[1] += get_pcvar_float(SPRING_MOVE_CVAR);
        case 4: vOrigin[1] -= get_pcvar_float(SPRING_MOVE_CVAR);
        case 5: vOrigin[2] += get_pcvar_float(SPRING_MOVE_CVAR);
        case 6: vOrigin[2] -= get_pcvar_float(SPRING_MOVE_CVAR);
    }

    engfunc(EngFunc_SetOrigin, ent, vOrigin);
    return PLUGIN_HANDLED;
}

stock fm_set_rendering(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16) //свечение модели
{
    new Float:RenderColor[3];

    RenderColor[0] = float(r);
    RenderColor[1] = float(g);
    RenderColor[2] = float(b);

    set_pev(entity, pev_renderfx, fx);
    set_pev(entity, pev_rendercolor, RenderColor);
    set_pev(entity, pev_rendermode, render);
    set_pev(entity, pev_renderamt, float(amount));

    return 1;
}

stock fm_get_aim_origin(index, Float:origin[3]) //fm_get_aim_origin - портирована из функции ядра AMXX get_user_origin(..., 3)
{
    new Float:start[3], Float:view_ofs[3];

    pev(index, pev_origin, start);
    pev(index, pev_view_ofs, view_ofs);
    xs_vec_add(start, view_ofs, start);

    new Float:dest[3];

    pev(index, pev_v_angle, dest);
    engfunc(EngFunc_MakeVectors, dest);
    global_get(glb_v_forward, dest);
    xs_vec_mul_scalar(dest, 9999.0, dest);
    xs_vec_add(start, dest, dest);

    engfunc(EngFunc_TraceLine, start, dest, 0, index, 0);
    get_tr2(0, TR_vecEndPos, origin);

    return 1;
}

stock fm_set_user_godmode(index, godmode = 0) //Для бессмертия
{
    set_pev(index, pev_takedamage, godmode == 1 ? DAMAGE_NO : DAMAGE_AIM);
    return 1;
}
Назад
Сверху