Иконка ресурса

[ACS] INJECTION 1.0.8.1

Нет прав для скачивания
Код:
#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <hamsandwich>
#include <reapi>

#define ACS_INJ_SOUND_NOTIFY        "buttons/bell1.wav"
#define ACS_INJ_SOUND_REJECT        "buttons/button2.wav"
#define is_valid_player(%0)            bool:is_user_connected(%0)
#define _SC(%0)                        %0, charsmax(%0)
#define _SCC(%0)                    acs_injections[id][%0], charsmax(acs_injections[][%0])
#define FFADE_IN                    0x0000        // Just here so we don't pass 0 into the function
#define FFADE_OUT                    0x0001        // Fade out (not in)
#define FFADE_MODULATE                0x0002        // Modulate (don't blend)
#define FFADE_STAYOUT                0x0004        // ignores the duration, stays faded out until new ScreenFade message received

enum _:ACS_STOP_THROTTLING {
    bool:FLAG,
    Float:LAST_USAGE
};

enum _:CVARS {
    PREFIX[64], ACCESS[32], COMMANDS[512], SPAWN_BONUS_COUNT, SPAWN_BONUS_STEAM_COUNT, USE_METHOD, SPEED, SPEED_DYNAMIC, BLOCK, Float:NEXT_ATTACK,
    HEALTH, HEALTH_STR[256], MAX_TIMES, MAX_COUNT, SEQUENCE, COST, BAR, VIP, DIFF, DIFF_MODE, KILL, V_MODEL[MAX_RESOURCE_PATH_LENGTH], P_MODEL[MAX_RESOURCE_PATH_LENGTH],
    PRE_SAMPLE[MAX_RESOURCE_PATH_LENGTH], SAMPLE[MAX_RESOURCE_PATH_LENGTH], CHEAT, ENABLE, SPAWN, AES_BUY_COUNT, CMD_COUNT, NOTIFY_MODE, NOTIFY_SOUND_MODE
};  

enum _:INJECT_DATA {
    USED, COUNT, HEALTH_SHOT, bool:IS_STEAM, Float:REMAINS_INJECT,
    bool:IS_INJECT, WEAPON, Float:CURE_TIME, CURE_SPEED,
    WEAPON_V_MODEL[MAX_RESOURCE_PATH_LENGTH], WEAPON_P_MODEL[MAX_RESOURCE_PATH_LENGTH]
};

#define ACS_INJ_SOUND_MASK (~30) // Какие сообщения выводить без звукового сопровождения и контроля троттлинга
enum _:NOTIFY_MODE {
    INJ_SHOW_GET = 1,            // Сопровождается звуком NOTIFY (сообщение с уведомлением о способе использования шприца)
    INJ_SHOW_TOTAL = 2,            // Без звука
    INJ_SHOW_LEFT = 4,            // Без звука
    INJ_SHOW_PARTIAL = 8,        // Без звука
    INJ_SHOW_FULL = 16,            // Без звука
    INJ_SHOW_FADE = 32,            // Сопровождается звуком исцеления
    INJ_SHOW_BLINK = 64,        // Сопровождается звуком REJECT
    INJ_SHOW_ERROR = 128        // Сопровождается звуком REJECT
}

new CVAR[CVARS];
new acs_injections[MAX_PLAYERS + 1][INJECT_DATA];
new ACS_PRINT_THR[MAX_PLAYERS + 1][ACS_STOP_THROTTLING];

public plugin_precache() {
    register_plugin("ACS injection med-kit", "1.0.8.1", "DEV-CS.RU");
    acs_create_cvars();
}

public plugin_natives() {
    register_native("acs_inj_get_user_injections", "native_acs_inj_get_injections");
    register_native("acs_inj_add_user_injections", "native_acs_inj_add_injections");
    register_native("acs_inj_reset_user_injections", "native_acs_inj_reset_injections");
    register_native("acs_inj_get_user_injects", "native_acs_inj_get_injects");
    register_native("acs_inj_is_user_injected", "native_acs_inj_is_injected");
    register_native("acs_inj_is_user_injection", "native_acs_inj_is_injection");
}

public plugin_init() {
    if (!register_dictionary("acs_injection.txt"))
        server_print("[ACS_INJECT] Error: not fount dictionary <acs_injection.txt>");
    register_event("CurWeapon", "check_weapon", "be", "1=1");
    RegisterHamPlayer(Ham_Spawn, "CBasePlayer_Spawn", true);
    RegisterHamPlayer(Ham_Killed, "CBasePlayer_Killed", true);
    RegisterHam(Ham_Item_Deploy, "weapon_knife", "CBasePlayerWeapon_Deploy", true);
    RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "CBasePlayer_OnSpawnEquip", true);
    RegisterHookChain(RG_CBasePlayerWeapon_CanDeploy, "CBasePlayerWeapon_CanDeploy_Pre");
}

public client_putinserver(id) {
    // Используем STEAM только если игрок не соответствует флагам доступа (чтобы различить количество выдаваемых в начале раунда шприцов по кварам)
    acs_injections[id][IS_STEAM] = CVAR[SPAWN_BONUS_STEAM_COUNT] && (!((get_user_flags(id) & read_flags(CVAR[ACCESS])) || (!read_flags(CVAR[ACCESS])))) && is_user_steam(id);
    acs_injections[id][HEALTH_SHOT] = acs_inj_get_flags_value_num(id, CVAR[HEALTH_STR]);
    acs_inj_reset(id, true);
}

public CBasePlayer_OnSpawnEquip(id) {
    acs_inj_reset(id);
    if (CVAR[SPAWN])
        acs_injections[id][COUNT] = 0;
    if ((CVAR[SPAWN_BONUS_COUNT] || CVAR[SPAWN_BONUS_STEAM_COUNT]) && acs_inj_check_access(id))
        acs_inj_add_injection_count(id, acs_injections[id][IS_STEAM] ? CVAR[SPAWN_BONUS_STEAM_COUNT] : CVAR[SPAWN_BONUS_COUNT]);
}

public CBasePlayer_Spawn(id) {
    acs_inj_reset(id);
}

public CBasePlayer_Killed(id) {
    acs_inj_reset(id);
    if (CVAR[KILL])
        acs_injections[id][COUNT] = 0;
}

public CBasePlayerWeapon_CanDeploy_Pre(const weapon) {
    static id;
    if (CVAR[BLOCK]
        && !acs_is_nullent(weapon)
        && (id = get_member(weapon, m_pPlayer))
        && is_valid_player(id)
        && acs_injections[id][IS_INJECT]) {
        SetHookChainReturn(ATYPE_INTEGER, 0);
        return HC_SUPERCEDE;
    }
    return HC_CONTINUE;
}

public check_weapon(id) {
    // Если во время анимации переключили оружие, останавливаем лечение
    if (is_valid_player(id) && acs_injections[id][IS_INJECT] && get_member(id, m_pActiveItem) != get_member(id, m_rgpPlayerItems, KNIFE_SLOT))
        acs_injections[id][IS_INJECT] = false;
}

public bool:Command_BuyMedkit(id) {
    return acs_inj_add_injection_count(id, CVAR[AES_BUY_COUNT]);
}

public bool:acs_inj_check_access(id) {
    return is_valid_player(id) ? ((get_user_flags(id) & read_flags(CVAR[ACCESS])) || (!read_flags(CVAR[ACCESS])) || acs_injections[id][IS_STEAM]) : false;
}

public bool:acs_inj_add_injection_count(id, count) {
    new bool:b_result, i_count;
    if ((b_result = (count > 0))) {
        if ((b_result = (acs_injections[id][USED] < CVAR[MAX_TIMES]))) {
            if ((b_result = (acs_injections[id][COUNT] < CVAR[MAX_COUNT]))) {
                // Если выдаем (покупаем) больше лимита - обрезаем под лимит, чтобы получить хоть сколько-нибудь шприцов, а не ошибку
                i_count = ((acs_injections[id][COUNT] + count) <= CVAR[MAX_COUNT]) ? count : (CVAR[MAX_COUNT] - acs_injections[id][COUNT]);
                acs_injections[id][COUNT] += i_count;
                if (i_count == 1)
                    acs_client_print(id, INJ_SHOW_GET, "%L", id, "INJ_GET_INJECT");
                else
                    acs_client_print(id, INJ_SHOW_GET, "%L", id, "INJ_GET_INJECT_COUNT", i_count, fmt("%L", id, fmt("INJ_COUNT_%d_SUFFIX", (i_count % 10))));
                if (acs_injections[id][COUNT] > 1)
                    acs_client_print(id, INJ_SHOW_TOTAL, "%L", id, "INJ_TOTAL_COUNT", acs_injections[id][COUNT], fmt("%L", id, fmt("INJ_COUNT_%d_SUFFIX", acs_injections[id][COUNT] % 10)));
            } else
                acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_MAX_COUNT");
        } else
            acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_LIMIT");  
    }
    return b_result;
}

public cmd_injection(id) {
    if (acs_inj_check_access(id)) {
        if (acs_inj_can_get_inject(id))
            acs_inj_add_injection_count(id, CVAR[CMD_COUNT]);          
    } else
        acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_ACCESS");
    return PLUGIN_HANDLED;
}

public @use_injection(id) {
    new Float:f_inj_time, Float:CUR_HEALTH, Float:MAX_HEALTH, Float:HEALTH_UP;
    if (acs_inj_can_use_inject(id)) {
        acs_injections[id][WEAPON] = get_member(id, m_pActiveItem);
        CUR_HEALTH = Float:get_entvar(id, var_health);
        MAX_HEALTH = Float:get_entvar(id, var_max_health);
        // Если лечим не до максимального уровня, проверяем остаток
        if (acs_injections[id][HEALTH_SHOT] > 0)
            // Если Не закончили лечение, продолжаем
            if (acs_injections[id][REMAINS_INJECT] > 0)
                HEALTH_UP = acs_injections[id][REMAINS_INJECT];
            // Иначе начинаем новое
            else
                HEALTH_UP = float(acs_injections[id][HEALTH_SHOT]);
        else
            HEALTH_UP = MAX_HEALTH - CUR_HEALTH;
        acs_injections[id][REMAINS_INJECT] = HEALTH_UP;
        switch (CVAR[SPEED_DYNAMIC]) {
            case 1:
                acs_injections[id][CURE_SPEED] = floatround(CVAR[SPEED] * (CUR_HEALTH / (MAX_HEALTH - acs_injections[id][HEALTH_SHOT]))) + 2;
            case 2:
                acs_injections[id][CURE_SPEED] = floatround(CVAR[SPEED] * (HEALTH_UP / acs_injections[id][HEALTH_SHOT])) + 2;
            case 3:
                acs_injections[id][CURE_SPEED] = floatround(CVAR[SPEED] * (CUR_HEALTH / (MAX_HEALTH - acs_injections[id][HEALTH_SHOT])) * (HEALTH_UP / acs_injections[id][HEALTH_SHOT])) + 2;
            default:
                acs_injections[id][CURE_SPEED] = CVAR[SPEED];
        }
        f_inj_time = acs_injections[id][REMAINS_INJECT] / acs_injections[id][CURE_SPEED];
        //console_print(id, "[DEBUG] CURR = %f, MAX = %f, SPEED = %d, TIME = %f", CUR_HEALTH, MAX_HEALTH, acs_injections[id][CURE_SPEED], f_inj_time);
        acs_inj_set_knife(id, false);
        if (CVAR[V_MODEL][0] && CVAR[P_MODEL][0]) {
            // Сохраняем текущую модель оружия (на случай отсутствия ножа в экипировке)
            get_entvar(id, var_viewmodel, _SCC(WEAPON_V_MODEL));
            get_entvar(id, var_weaponmodel, _SCC(WEAPON_P_MODEL));
            // Устанавливаем модель для анимации шприца
            set_entvar(id, var_viewmodel, CVAR[V_MODEL]);
            set_entvar(id, var_weaponmodel, CVAR[P_MODEL]);
            acs_send_weapon_anim(id, CVAR[SEQUENCE]);
        }
        set_member(id, m_flNextAttack, f_inj_time);
        if (CVAR[BAR] && f_inj_time > 1.0)
            rg_send_bartime(id, floatround(f_inj_time));
        if (CVAR[PRE_SAMPLE][0])
            rh_emit_sound2(id, 0, CHAN_ITEM, CVAR[PRE_SAMPLE]);
        acs_injections[id][CURE_TIME] = 0.0;
        acs_injections[id][IS_INJECT] = true;
        //console_print(id, "[DEBUG] is_inject = %d", acs_injections[id][IS_INJECT]);
        RequestFrame("@inject_engine", id)
        return PLUGIN_HANDLED;
    }
    return PLUGIN_CONTINUE;
}

@inject_engine(id) {
    new Float:f_time, s_classname[8];
    if ((!acs_injections[id][IS_INJECT]) || get_member_game(m_bRoundTerminating)) {
        if (is_valid_player(id)) {
            acs_injections[id][IS_INJECT] = false;
            if (CVAR[BAR])
                rg_send_bartime(id, 0);
            if (is_user_alive(id)) {
                if ((get_member(id, m_pActiveItem) == get_member(id, m_rgpPlayerItems, KNIFE_SLOT)))
                        if ((!acs_is_nullent(acs_injections[id][WEAPON]))) {
                            get_entvar(acs_injections[id][WEAPON], var_classname, _SC(s_classname))
                            if ((contain(s_classname, "weapon_") == 0) && (get_member(acs_injections[id][WEAPON], m_pPlayer) == id))
                                rg_switch_weapon(id, acs_injections[id][WEAPON]);
                            else
                                acs_inj_set_knife(id);
                        } else
                            acs_inj_set_knife(id);
                set_member(id, m_flNextAttack, CVAR[NEXT_ATTACK]);
                if (acs_injections[id][REMAINS_INJECT] == 0.0) {
                    if (CVAR[NOTIFY_MODE] & INJ_SHOW_FADE)
                        acs_screen_fade(id, { 0, 200, 0 }, 1.5, 0.6, 200);
                    if (CVAR[NOTIFY_SOUND_MODE] & INJ_SHOW_FADE)
                        rh_emit_sound2(id, 0, CHAN_ITEM, CVAR[SAMPLE]);
                    // Проверяем, чтобы не уйти в минус (сторонние плагины могут забрать шприцы в процессе лечения)
                    if (acs_injections[id][COUNT] > 0)
                        acs_injections[id][COUNT]--;
                    else
                        acs_injections[id][COUNT] = 0;
                    acs_injections[id][USED]++;
                    if (acs_injections[id][COUNT])
                        acs_client_print(id, INJ_SHOW_LEFT, "%L", id, "INJ_LEFT_COUNT", fmt("%L", id, fmt("INJ_COUNT_%d_PREFIX", (acs_injections[id][COUNT] % 10))), acs_injections[id][COUNT], fmt("%L", id, fmt("INJ_COUNT_%d_SUFFIX", (acs_injections[id][COUNT] % 10))));
                }          
                if (Float:get_entvar(id, var_health) == Float:get_entvar(id, var_max_health))
                    acs_client_print(id, INJ_SHOW_FULL, "%L", id, "INJ_SUCCESFULLY_INJECTED_FULL");
                else
                    acs_client_print(id, INJ_SHOW_PARTIAL, "%L", id, "INJ_SUCCESFULLY_INJECTED");
            }
            rg_add_account(id, -CVAR[COST]); // Никаких кредитов, списываем деньги сразу по окончании лечения, чтобы пациент не сдох раньше оплаты
        }
    } else {
        f_time = get_gametime();
        if (acs_injections[id][CURE_TIME] < f_time) {
            //console_print(id, "[DEBUG] f_time = %f, cure_time = %f, cure_speed = %d", f_time, acs_injections[id][CURE_TIME], acs_injections[id][CURE_SPEED]);
            acs_injections[id][REMAINS_INJECT] -= 1.0;
            if (!(ExecuteHamB(Ham_TakeHealth, id, 1.0, DMG_GENERIC) && acs_injections[id][REMAINS_INJECT] > 0.0)) {
                acs_injections[id][REMAINS_INJECT] = 0.0;
                acs_injections[id][IS_INJECT] = false;
            }
            acs_injections[id][CURE_TIME] = f_time + 1.0 / acs_injections[id][CURE_SPEED];
        }
        RequestFrame("@inject_engine", id);
    }
}

public CBasePlayerWeapon_Deploy(weapon) {
    static id;
    if (CVAR[CHEAT]
            && (id = get_member(weapon, m_pPlayer))
            && is_valid_player(id)
            && !acs_injections[id][IS_INJECT]
            && !acs_injections[id][COUNT]
            && (Float:get_entvar(id, var_health) < Float:get_entvar(id, var_max_health) / 2.0)
            && !random(5))
        acs_inj_add_injection_count(id, 1);
}

acs_create_cvars() {
    new s_cmd_name[32];
    bind_pcvar_string(create_cvar("acs_inj_prefix", "^4[Injection]", .description = "Префикс в чате"), _SC(CVAR[PREFIX]));
    bind_pcvar_num(create_cvar("acs_inj_enable", "1", .description = "0 - Выкл. 1 - Вкл.", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[ENABLE]);
    bind_pcvar_string(create_cvar("acs_inj_access", "s", .description = "Флаги доступа (оставьте пустым для выдачи всем игрокам)"), _SC(CVAR[ACCESS]));
    bind_pcvar_string(create_cvar("acs_inj_commands", "/acs_injection /acs_inject", .description = "Команды для получения шприца (оставьте пустым чтобы отключить)"), _SC(CVAR[COMMANDS]));
    bind_pcvar_num(create_cvar("acs_inj_spawn_bonus_count", "1", .description = "Сколько шприцов выдавать бесплатно в начале раунда игрокам с флагами доступа", .has_min=true, .min_val=0.0, .has_max=true, .max_val=10.0), CVAR[SPAWN_BONUS_COUNT]);
    bind_pcvar_num(create_cvar("acs_inj_spawn_bonus_steam_count", "1", .description = "Сколько шприцов выдавать бесплатно в начале раунда игрокам STEAM (не используется, если флаги доступа не заданы)", .has_min=true, .min_val=0.0, .has_max=true, .max_val=10.0), CVAR[SPAWN_BONUS_STEAM_COUNT]);
    bind_pcvar_num(create_cvar("acs_inj_aes_buy_count", "1", .description = "Сколько шприцов выдавать при покупке через AES-Bonus", .has_min=true, .min_val=1.0, .has_max=true, .max_val=10.0), CVAR[AES_BUY_COUNT]);
    bind_pcvar_num(create_cvar("acs_inj_cmd_count", "1", .description = "Сколько шприцов выдавать по команде acs_inj_commands", .has_min=true, .min_val=1.0, .has_max=true, .max_val=10.0), CVAR[CMD_COUNT]);
    bind_pcvar_num(create_cvar("acs_inj_use_method", "4", .description = "Метод использования:^n0 - через Z (radio1)^n1 - через X (radio2)^n2 - через C (radio3)^n3 - через Q (drop)^n4 - через F (<фонарь> - impulse 100)", .has_max = true, .max_val = 4.0), CVAR[USE_METHOD]);
    bind_pcvar_num(create_cvar("acs_inj_speed", "10", .description = "Скорость лечения (HP в секунду)", .has_min=true, .min_val=1.0, .has_max=true, .max_val=100.0), CVAR[SPEED]);
    bind_pcvar_num(create_cvar("acs_inj_speed_dynamic", "3", .description = "Изменять время лечения в зависимости от:^n 0 - Выкл.^n1 - текущей величины здоровья^n2 - неиспользованного остатка шприца^n3 - оба варианта", .has_min=true, .min_val=0.0, .has_max=true, .max_val=3.0), CVAR[SPEED_DYNAMIC]);
    bind_pcvar_num(create_cvar("acs_inj_block", "0", .description = "Блокировать смену оружия в процессе лечения", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[BLOCK]);
    bind_pcvar_float(create_cvar("acs_inj_next_attack", "0.0", .description = "Через сколько секунд после лечения можно стрелять", .has_min=true, .min_val=0.0, .has_max=true, .max_val=10.0), CVAR[NEXT_ATTACK]);
    bind_pcvar_num(create_cvar("acs_inj_health", "30", .description = "Величина пополняемого здоровья, 0 - MAX ", .has_min = true, .has_max = true, .min_val = 0.0, .max_val = 100.0), CVAR[HEALTH]);
    bind_pcvar_string(create_cvar("acs_inj_health_flags", "", .description = "Величина пополняемого здоровья в зависимости от флагов, в формате флаги:здоровье через запятую"), _SC(CVAR[HEALTH_STR]));
    bind_pcvar_num(create_cvar("acs_inj_max_use", "3", .description = "Максимальное кол-во использований за раунд", .has_min = true, .min_val = 1.0, .has_max=true, .max_val=10.0), CVAR[MAX_TIMES]);
    bind_pcvar_num(create_cvar("acs_inj_max_count", "3", .description = "Сколько максимально игрок может иметь с собой шприцов", .has_min=true, .min_val=0.0, .has_max=true, .max_val=10.0), CVAR[MAX_COUNT]);  
    bind_pcvar_num(create_cvar("acs_inj_sequence", "0", .description = "Индекс анимации модели шприца", .has_min=true, .min_val=0.0, .has_max=true, .max_val=100.0), CVAR[SEQUENCE]);
    bind_pcvar_num(create_cvar("acs_inj_cost", "0", .description = "Стоимость услуги", .has_min=true, .min_val=0.0, .has_max=true, .max_val=16000.0), CVAR[COST]);
    bind_pcvar_num(create_cvar("acs_inj_bar", "1", .description = "Включить линию прогресса", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[BAR]);
    bind_pcvar_num(create_cvar("acs_inj_vip", "0", .description = "Запретить VIP игроку использовать шприц на as_* картах", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[VIP]);
    bind_pcvar_num(create_cvar("acs_inj_win_diff", "5", .description = "Если разница между победами команд превышает это значение, блокировать шприц для доминантной команды (0 - Выкл.)", .has_min=true, .min_val=0.0, .has_max=true, .max_val=10.0), CVAR[DIFF]);
    bind_pcvar_num(create_cvar("acs_inj_win_diff_mode", "0", .description = "Режим определения доминантной команды:^n0 - доминирование на N очков^n1 - имеет подряд N побед", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[DIFF_MODE]);
    bind_pcvar_num(create_cvar("acs_inj_notify_mode", "255", .description = "Режим вывода уведомлений по действиям шприца:^n0 - Выкл.^n1 - получение шприца^n2 - количествово шприцов с собой^n4 - остаток шприцов^n8 - частичное излечение^n16 - полное излечение^n32 - затемнение экрана при полном использовании шприца^n64 - мигание строки баланса^n128 - ошибки по действиям шприца^n(для произвольной комбинации необходимо сложить значения нужных пунктов)", .has_min=true, .min_val=0.0, .has_max=true, .max_val=255.0), CVAR[NOTIFY_MODE]);
    bind_pcvar_num(create_cvar("acs_inj_notify_sound_mode", "160", .description = "Режим сопровождения звуком уведомлений по действиям шприца:^n0 - Выкл.^n1 - получение шприца^n32 - после иньекции^n128 - ошибки^n(для произвольной комбинации необходимо сложить значения нужных пунктов)", .has_min=true, .min_val=0.0, .has_max=true, .max_val=255.0), CVAR[NOTIFY_SOUND_MODE]);
    bind_pcvar_num(create_cvar("acs_inj_spawn_reset", "1", .description = "Обнулять кол-во шприцов в начале раунда", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[SPAWN]);
    bind_pcvar_num(create_cvar("acs_inj_kill_reset", "1", .description = "Обнулять кол-во шприцов после смерти", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[KILL]);
    bind_pcvar_num(create_cvar("acs_inj_cheat", "1", .description = "Выдать шприц с 20% вероятностью игроку со здоровьем <50 при переключении оружия", .has_min=true, .min_val=0.0, .has_max=true, .max_val=1.0), CVAR[CHEAT]);
    bind_pcvar_string(create_cvar("acs_inj_v_model", "models/v_healshot.mdl", .description = "V модель шприца (опционально)"), _SC(CVAR[V_MODEL]));
    bind_pcvar_string(create_cvar("acs_inj_p_model", "models/p_healshot.mdl", .description = "P модель шприца (опционально)"), _SC(CVAR[P_MODEL]));
    bind_pcvar_string(create_cvar("acs_inj_pre_sample", "injection/pre_medshot.wav", .description = "Звук до иньекции (опционально)"), _SC(CVAR[PRE_SAMPLE]));
    bind_pcvar_string(create_cvar("acs_inj_sample", "injection/medshot.wav", .description = "Звук после иньекции (опционально)"), _SC(CVAR[SAMPLE]));
    acs_config(true, "acs_injection");
    acs_precache(CVAR[PRE_SAMPLE]);
    acs_precache(CVAR[SAMPLE]);
    acs_precache(CVAR[V_MODEL], true);
    acs_precache(CVAR[P_MODEL], true);
    while (argbreak(CVAR[COMMANDS], _SC(s_cmd_name), _SC(CVAR[COMMANDS])) != INVALID_HANDLE) {
        if (s_cmd_name[0] == '/' || s_cmd_name[0] == '!' || s_cmd_name[0] == '.') {
            register_clcmd(fmt("say %s", s_cmd_name), "cmd_injection");
            register_clcmd(fmt("say_team %s", s_cmd_name), "cmd_injection");
        } else
            register_clcmd(s_cmd_name, "cmd_injection", CVAR[ACCESS]);
    }
    switch (CVAR[USE_METHOD]) {
        case 0: register_clcmd("radio1", "@use_injection");
        case 1: register_clcmd("radio2", "@use_injection");
        case 2: register_clcmd("radio3", "@use_injection");
        case 3: register_clcmd("drop", "@use_injection");
        case 4: register_impulse(100, "@use_injection");
    }
}

stock acs_precache(const file[], bool:is_model = false) {
    if (file[0])
        if ((is_model && file_exists(file)) || (!is_model && file_exists(fmt("sound/%s", file))))
            return is_model ? precache_model(file) : precache_sound(file);
        else
            set_fail_state("[FATAL ERROR] precache(): %s <%s> not found!", is_model ? "model" : "sound", file);
    return 0;
}

stock acs_config(const bool:auto_create = true, const name[] = "", const folder[] = "") {
    new s_config[MAX_RESOURCE_PATH_LENGTH];
    get_configsdir(_SC(s_config));
    if (folder[0])
        format(_SC(s_config), "%s/plugins/%s/%s.cfg", s_config, folder, name);
    else
        format(_SC(s_config), "%s/plugins/%s.cfg", s_config, name);
    AutoExecConfig(auto_create, name, folder);
    if (file_exists(s_config)) {
        server_cmd("exec %s", s_config);
        server_exec();
    }
}

stock acs_inj_set_knife(const id, bool:restore_model = true) {
    new i_weapon;
    if (acs_is_nullent((i_weapon = get_member(id, m_rgpPlayerItems, KNIFE_SLOT)))) {
        if (restore_model && acs_injections[id][WEAPON_V_MODEL][0] && acs_injections[id][WEAPON_P_MODEL][0]) {
            set_entvar(id, var_viewmodel, acs_injections[id][WEAPON_V_MODEL]);
            set_entvar(id, var_weaponmodel, acs_injections[id][WEAPON_P_MODEL]);
        }
    } else
        rg_switch_weapon(id, i_weapon);
}

stock acs_inj_reset(const id, bool:is_full = false) {
    acs_injections[id][IS_INJECT] = false;
    acs_injections[id][REMAINS_INJECT] = 0.0;
    acs_injections[id][USED] = 0;
    if (is_full)
        acs_injections[id][COUNT] = 0;
}

stock acs_inj_get_flags_value_num(const id, const flags_str[]) {
    new i_flags, s_tmp[32], s_flags[24], s_value[8], i_value, s_buff[256], i_result = CVAR[HEALTH];
    // Если лечим до максимального здоровья по-умолчанию, флаги не учитываем
    if (i_result && flags_str[0]) {
        i_flags = get_user_flags(id);
        copy(_SC(s_buff), flags_str);
        do {
            strtok(s_buff, _SC(s_tmp), _SC(s_buff), ',', 1);
            strtok(s_tmp, _SC(s_flags), _SC(s_value), ':', 1);
            if ((read_flags(s_flags) & i_flags) && (i_value = str_to_num(s_value)) > i_result)
                i_result = i_value;
        } while (s_buff[0]);
    }
    return i_result;
}

public native_acs_inj_get_injections(const plugin_id, const argc) {
    enum { arg_id = 1 }
    new id = get_param(arg_id);
    return is_valid_player(id) ? acs_injections[id][COUNT] : 0;
}

public native_acs_inj_add_injections(const plugin_id, const argc) {
    enum { arg_id = 1, arg_add_value }
    new id, add_value, bool:b_result;
    id = get_param(arg_id);
    add_value = get_param(arg_add_value);
    if ((b_result = bool:is_user_alive(id)))
        //Проверяем чтобы не уйти в минус
        if (acs_injections[id][COUNT] + add_value >= 0)
            acs_injections[id][COUNT] += add_value;
    return b_result;
}

public native_acs_inj_reset_injections(plugin_id, num_params) {
    enum { arg_id = 1 }
    new id, bool:b_result;
    id = get_param(arg_id);
    if ((b_result = is_valid_player(id)))
        acs_injections[id][COUNT] = 0;
    return b_result;
}

public native_acs_inj_get_injects(plugin_id, num_params) {
    enum { arg_id = 1 }
    new id = get_param(arg_id);
    return is_valid_player(id) ? acs_injections[id][USED] : 0;
}

public native_acs_inj_is_injected(plugin_id, num_params) {
    enum { arg_id = 1 }
    new id = get_param(arg_id);
    return is_valid_player(id) ? (acs_injections[id][USED] > 0) : false;
}

public native_acs_inj_is_injection(plugin_id, num_params) {
    enum { arg_id = 1 }
    new id = get_param(arg_id);
    return is_user_alive(id) ? acs_injections[id][IS_INJECT] : false;
}

stock acs_check_throttling(id) {
    new Float:f_time, Float:f_delta;
    f_time = get_gametime();
    f_delta = f_time - ACS_PRINT_THR[id][LAST_USAGE];
    if (ACS_PRINT_THR[id][FLAG]) {
        if (f_delta > 4 * 0.75)
            ACS_PRINT_THR[id][FLAG] = false;
    } else if (f_delta < 0.75)
        ACS_PRINT_THR[id][FLAG] = true;
    ACS_PRINT_THR[id][LAST_USAGE] = f_time;
    return !ACS_PRINT_THR[id][FLAG];
}

stock acs_client_print(const id, const notify_mode, const message[], any:...) {
    static s_tmp[190];
    // Отключаем проверку троттлинга, если сообщение без звуковых уведомлений (если сообщения показываются подряд - второе и последующие должны быть без звука)
    if ((CVAR[NOTIFY_MODE] & notify_mode) && ((id == 0) || is_valid_player(id)) && (acs_check_throttling(id) || (!((CVAR[NOTIFY_SOUND_MODE] & ACS_INJ_SOUND_MASK) & notify_mode)))) {
        vformat(_SC(s_tmp), message, 4);
        if (CVAR[PREFIX])
            format(_SC(s_tmp), "%s %s", CVAR[PREFIX], s_tmp);
        client_print_color(id, ((notify_mode & INJ_SHOW_ERROR) ? print_team_red : print_team_blue), s_tmp);
        if ((CVAR[NOTIFY_SOUND_MODE] & ACS_INJ_SOUND_MASK) & notify_mode)
            acs_send_audio(id, ((notify_mode & INJ_SHOW_ERROR) ? ACS_INJ_SOUND_REJECT : ACS_INJ_SOUND_NOTIFY));
    }
}

stock bool:acs_inj_can_get_inject(id) {
    new bool:b_result = false;
    if (CVAR[ENABLE]) {
        if ((!(CVAR[VIP] && get_member(id, m_bIsVIP)))) {
            if (is_user_alive(id)) {
                if (!is_team_dominate(id)) {
                    if (!(b_result = (get_member(id, m_iAccount) >= CVAR[COST])))
                        acs_blink_account(id);
                } else
                    acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_DOMINA");
            } else
                acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_ALIVE");
        } else
            acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_VIP");
    }
    //console_print(id, "[DEBUG] can_get_inject = %d", b_result);
    return b_result;
}

stock bool:acs_inj_can_use_inject(id) {
    new bool:b_result, weapon;
    //console_print(id, "[DEBUG] used = %d, count = %d", acs_injections[id][USED], acs_injections[id][COUNT]);
    if ((!acs_injections[id][IS_INJECT])
            && (!get_member_game(m_bRoundTerminating))
            && acs_inj_can_get_inject(id)
            && (Float:get_entvar(id, var_health) < Float:get_entvar(id, var_max_health))) {
        if (acs_injections[id][COUNT]) {
            if ((b_result = acs_injections[id][USED] < CVAR[MAX_TIMES])) {
                if (b_result && (CVAR[USE_METHOD] < 4)) {
                    weapon = get_member(id, m_pActiveItem);
                    b_result = ((!acs_is_nullent(weapon)) && (get_member(weapon, m_iId) == CSW_KNIFE))
                }
            } else
                acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_LIMIT");
        } else
            acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_DONT_HAVE");  
    }
    return b_result;
}

stock acs_send_audio(const id, const sample[]) {
    static i_msg;
    if(sample[0]) {
        if ((id == 0) || is_valid_player(id)) {
            if(!i_msg)
                i_msg = get_user_msgid("SendAudio");
            message_begin(id ? MSG_ONE_UNRELIABLE : MSG_BROADCAST, i_msg, .player = id);
            {
                write_byte(id);
                write_string(sample);
                write_short(PITCH_NORM);
            }
            message_end();
        }
    }
}

stock bool:is_team_dominate(id) {
    new i_diff;
    return (CVAR[DIFF] && (get_member(id, m_iTeam) == acs_get_team_dominate(i_diff))) ? (i_diff > CVAR[DIFF]) : false;
}

stock TeamName:acs_get_team_dominate(&diff = 0) {
    new TeamName:t_team;
    if ((diff = (CVAR[DIFF_MODE] ? (get_member_game(m_iNumConsecutiveCTLoses) - get_member_game(m_iNumConsecutiveTerroristLoses)) : (get_member_game(m_iNumTerroristWins) - get_member_game(m_iNumCTWins))) > 0))
        t_team = TEAM_TERRORIST;
    else if (diff < 0)
        t_team = TEAM_CT;
    diff = abs(diff);
    return t_team;
}

stock acs_send_weapon_anim(const id, const sequence) {
    if (is_valid_player(id) && is_user_alive(id)) {
        set_entvar(id, var_weaponanim, sequence);
        message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
        {
            write_byte(sequence);
            write_byte(0);
        }
        message_end();
    }
}

stock acs_screen_fade(id = 0, v_color[3] = { 0, 0, 0 }, Float:f_time = -1.0, Float:hold_time = 0.0, alpha = 0, flags = FFADE_IN, bool:reliable = false) {
    static i_msg;
    new i_fade_time, i_msg_dest;
    if (is_valid_player(id) && is_user_alive(id)) {
        if (get_member(id, m_blindUntilTime) < get_gametime()) {
            if (f_time == -1.0)
                i_fade_time = 4;
            else
                i_fade_time = clamp(floatround(f_time * (1 << 12)), 0, 0xFFFF);
            if (!i_msg)
                i_msg = get_user_msgid("ScreenFade");
            if (reliable)
                i_msg_dest = id ? MSG_ONE : MSG_ALL;
            else
                i_msg_dest = id ? MSG_ONE_UNRELIABLE : MSG_BROADCAST;
            message_begin(i_msg_dest, i_msg, .player = id);
            {
                write_short(i_fade_time);
                write_short(clamp(floatround(hold_time * (1 << 12)), 0, 0xFFFF));
                write_short(flags);
                write_byte(v_color[0]);
                write_byte(v_color[1]);
                write_byte(v_color[2]);
                write_byte(alpha);
            }
            message_end();
        }
    }
}

stock acs_blink_account(id) {
    static i_msg;
    if (is_valid_player(id) && is_user_alive(id)) {
        if ((CVAR[NOTIFY_MODE] & INJ_SHOW_ERROR))
            acs_client_print(id, INJ_SHOW_ERROR, "%L", id, "INJ_NOT_ENOUGH");
        if ((CVAR[NOTIFY_MODE] & INJ_SHOW_BLINK) && (i_msg || (i_msg = get_user_msgid("BlinkAcct")))) {
            message_begin(MSG_ONE_UNRELIABLE, i_msg, .player = id);
            {
                write_byte(3);
            }
            message_end();
        }
    }
}

stock bool:acs_is_nullent(entity) {
    return entity == 0 || is_entity(entity) == false;
}
Назад
Верх