[Reapi] Molotov

reapi [Reapi] Molotov 2.5.1

Нет прав для скачивания
Автор
wellasgood`
Исходный код
C++:
#pragma semicolon 0

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#include <reapi_molotov_api>

//поддержка gamecms купленной услуги
#tryinclude <gamecms5>

#define CVAR_DESC(%0) fmt("%L", LANG_SERVER, %0)

enum
{
    MOLOTOV_ANIM_PULLPIN = 1,
    MOLOTOV_ANIM_DRAW = 3
}

enum
{
    TASK_ID = 666,
    TASK_ID2,
    TASK_ID3,
    TASK_ID4
}

enum _:EFF_SETTINGS_DATA
{
    EFF_TIME_INTERVAL,
    EFF_LIFE,
    EFF_WIDTH,
    EFF_BRIGHTNESS
}

enum _:EFF_COLOR_DATA
{
    EFF_CT_R,
    EFF_CT_G,
    EFF_CT_B,
    EFF_T_R,
    EFF_T_G,
    EFF_T_B
}

enum _:EFF_COLOR_RND_DATA
{
    EFF_CT_R_MIN,
    EFF_CT_R_MAX,
    EFF_CT_G_MIN,
    EFF_CT_G_MAX,
    EFF_CT_B_MIN,
    EFF_CT_B_MAX,
    EFF_T_R_MIN,
    EFF_T_R_MAX,
    EFF_T_G_MIN,
    EFF_T_G_MAX,
    EFF_T_B_MIN,
    EFF_T_B_MAX
}

enum any:CVAR_DATA
{
    ACCESS[64],
    USE_PICKUP,
    ACCESS_PICKUP[64],
    DMG_TM,
    Float:DMG,
    Float:FIRETIME,
    Float:RADIUS,
    Float:DMG_TICK,
    Float:ANIM_TICK,
    LONG_DELAY_USE,
    Float:LONG_DELAY_TIME,
    LONG_DELAY_KILL,
    Float:TIME_OF_DETONATE,
    Float:IMPACT_SOUND_TIME,
    GET_IN_SPAWN,
    EXTINGUISHING,
    Float:EXTINGUISHING_TIME,
    Float:RADIUS_MULTIPLIER,
    RESTRICTION_ON_USE,
    TIME_LIMIT_ON_USAGE,
    INFINITE_USAGE_FLAGS[64],
    Float:FIRE_EFF,
    ROUND_LIMIT_ISSUING,
    ERROR_SOUND_PATH_AND_NAME[64],
    BUY_MOLOTOV,
    MOLOTOV_COST,
    ROUND_LIMIT_BUY,
    PLAY_ERROR_SOUND,
    PLAY_ERROR_SOUND_MODE,
    CHECKING_BUY_ZONE,
    TIME_TO_BUY,
    ACCESS_SPAWN[64],
    GIVE_LIMIT,
    GIVE_BUY_ZONE,
    GIVE_TIME_TO_BUY,
    RANDOM_DAMAGE[32],
    DAMAGE_FLAGS,
    EFFECT_TEAM_DESIGNATION,
    EFFECT_COLOR_CT_AND_T[32],
    OTHER_EFFECT_SETTINGS[32],
    EFFECT_CIRCLE_COLOR_MODES,
    EFFECT_COLOR_CT_AND_T_RND[64]
}

new const PLUGIN_VER[] = "2.5.1"

new const MOLOTOV_FIRE_CLASSNAME[] = "ent_molotov_fire"
new const WEAPON_NAME[] = "weapon_smokegrenade"
new const AMMO_NAME[] = "Molotov"
new const WEAPON_NEW_NAME[] = "reapi_molotov/weapon_molotov"
new const ITEM_CLASSNAME[] = "weapon_molotov"
new const GRENADE_CLASSNAME[] = "molotov"

new const SPRITE_CIRCLE[] = "sprites/laserbeam.spr" //Спрайт для эффекта цветного круга (стандартный из папки valve)

const OBJECT_MOLOTOV_FIRE = 5123
const WeaponIdType:WEAPON_ID = WEAPON_SMOKEGRENADE
const WeaponIdType:WEAPON_NEW_ID = WEAPON_GLOCK
const WeaponIdType:WEAPON_FAKE_ID = WeaponIdType:75
const AMMO_ID = 16

#if defined _gamecms5_included
 new GAME_CMS_SERVICES[128], INFINITE_USAGE_FLAGS_GAMECMS[128]
 new bool:g_Value[2][MAX_PLAYERS+1]
#endif

new eCvarData[CVAR_DATA], CheckPlayerEnt[MAX_PLAYERS+1], CheckLong[MAX_PLAYERS+1], bool:CheckCheck[MAX_PLAYERS+1], BuyTime, GiveTime, SpwReadFlags
new MsgIdStatusIcon, MsgIdWeaponList, MsgIdAmmoPickup, Array:SaveModels, Array:SaveSound, Array:SaveSprites, Float:flCurTime2[MAX_PLAYERS+1], CheckRound
new InfReadFlags, AccReadFlags, PpReadFlags, CheckTime[MAX_PLAYERS+1], g_iModelIndex[4], Array:SaveGrenadeNames, GiveLimit[MAX_PLAYERS+1], SPRITE_CIRCLE_ID
new Float:rnd_dmg_min, Float:rnd_dmg_max, GlobalColorsEff[EFF_COLOR_DATA], GlobalColorsRndEff[EFF_COLOR_RND_DATA], GlobalSettingsEff[EFF_SETTINGS_DATA]

#if WEAPON_NEW_ID != WEAPON_GLOCK
 new FwdRegUserMsg, MsgHookWeaponList
#endif

//~forwards~
new forward_player_takes_damage, forward_molotov_exploded, forward_raising_molotov
new forward_molotov_dropped, forward_player_threw_molotov, forward_player_received_molotov

public plugin_precache()
{
    register_plugin("[ReAPI] Molotov", PLUGIN_VER, "wellasgood")

    SaveModels = ArrayCreate(64)
    SaveSound = ArrayCreate(64)
    SaveSprites = ArrayCreate(64)
    SaveGrenadeNames = ArrayCreate(64)

    LoadingResources()

#if WEAPON_NEW_ID != WEAPON_GLOCK
    MsgIdWeaponList = get_user_msgid("WeaponList")

    if(MsgIdWeaponList)
    {
        MsgHookWeaponList = register_message(MsgIdWeaponList, "@HookWeaponList")
    }
    else
    {
        FwdRegUserMsg = register_forward(FM_RegUserMsg, "@RegUserMsg_Post", true)
    }
#endif
}

LoadingResources()
{
    new Path[MAX_RESOURCE_PATH_LENGTH]
    get_localinfo("amxx_configsdir", Path, charsmax(Path))

    formatex(Path, charsmax(Path), "%s/reapi_molotov.ini", Path)

    if(!file_exists(Path))
    {
        set_fail_state("Нету файла 'reapi_molotov.ini' по пути 'addons/amxmodx/configs/'")
    }

    new Data[64], f = fopen(Path, "rt"), Section, iSprite

    while(!feof(f))
    {
        fgets(f, Data, charsmax(Data))
        trim(Data)

        if(!Data[0] || Data[0] == ';')
        {
            continue
        }

        if(Data[0] == '[')
        {
            if(containi(Data[1], "модели") == 0)
            {
                Section = 1
            }
            else if(containi(Data[1], "звуки") == 0)
            {
                Section = 2
            }
            else if(containi(Data[1], "спрайты") == 0)
            {
                Section = 3
            }
            else if(containi(Data[1], "команды выдачи") == 0)
            {
                Section = 4
            }
            else if(containi(Data[1], "тушение огня") == 0)
            {
                Section = 5
            }
            else if(containi(Data[1], "команды покупки") == 0)
            {
                Section = 6
            }
            else if(containi(Data[1], "команды на прямую выдачу") == 0)
            {
                Section = 7
            }

            continue
        }

        switch(Section)
        {
            case 1:
            {
                ArrayPushString(SaveModels, Data)
                precache_model(Data)
            }
            case 2:
            {
                ArrayPushString(SaveSound, Data)
                precache_sound(Data)
            }
            case 3:
            {
                if(iSprite < 2 || iSprite == 6) ArrayPushString(SaveSprites, Data)

                switch(iSprite)
                {
                    case 0, 1: precache_model(Data)
                    case 2, 3: precache_generic(Data)
                    case 4..7: g_iModelIndex[iSprite-4] = precache_model(Data)
                }

                iSprite++
            }
            case 4:
            {
                register_clcmd(Data, "@CmdGiveMolotov")
            }
            case 5:
            {
                ArrayPushString(SaveGrenadeNames, Data)
            }
            case 6:
            {
                register_clcmd(Data, "@CmdBuyMolotov")
            }
            case 7:
            {
                new Part1[57], Part2[7]
                strtok(Data, Part1, charsmax(Part1), Part2, charsmax(Part2), '~')

                if(equal(Part2, "srvcmd"))
                {
                    register_srvcmd(Part1, "@SrvCmdGettingMolotov", -1)
                }
                else
                {
                    register_clcmd(Data, "@CmdGettingMolotov")
                }
            }
        }
    }

    fclose(f)

    SPRITE_CIRCLE_ID = precache_model(SPRITE_CIRCLE)
}

public plugin_init()
{
    register_dictionary("reapi_molotov.txt")

    register_clcmd(WEAPON_NEW_NAME, "@CmdSelect")

    RegisterHookChain(RG_CSGameRules_RestartRound, "@CSGameRules_RestartRound_Pre", false)
    RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "@CBasePlayer_OnSpawnEquip_Post", true)
    RegisterHookChain(RG_CSGameRules_CleanUpMap, "@CSGameRules_CleanUpMap_Post", true)
    RegisterHookChain(RG_CBasePlayer_GiveAmmo, "@CBasePlayer_GiveAmmo_Pre", false)
    RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "@CBasePlayerWeapon_DefaultDeploy_Pre", false)
    RegisterHookChain(RG_CBasePlayer_Killed, "@CBasePlayer_Killed_Post", true)
    RegisterHookChain(RG_CBasePlayer_ThrowGrenade, "@CBasePlayer_ThrowGrenade_Pre", false)

    RegisterHam(Ham_Item_Deploy, WEAPON_NAME, "@Item_Deploy_Post", true)
    RegisterHam(Ham_Item_Holster, WEAPON_NAME, "@Item_Holster_Post", true)
    RegisterHam(Ham_Weapon_PrimaryAttack, WEAPON_NAME, "@Molotov_PrimaryAttack_Pre", false)
    RegisterHam(Ham_Weapon_SecondaryAttack, WEAPON_NAME, "@Molotov_SecondaryAttack_Pre", false)
    RegisterHam(Ham_Think, "env_sprite", "@FireMolotov_Think_Post", true)

    MsgIdStatusIcon = get_user_msgid("StatusIcon")
    MsgIdAmmoPickup = get_user_msgid("AmmoPickup")

#if WEAPON_NEW_ID == WEAPON_GLOCK
    MsgIdWeaponList = get_user_msgid("WeaponList")

    UTIL_WeapoList(
        MSG_INIT, 0,
        WEAPON_NEW_NAME,
        AMMO_ID, 1,
        -1, -1, GRENADE_SLOT, 4, WEAPON_NEW_ID,
        ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE
    )
#else
    if(FwdRegUserMsg)
    {
        unregister_forward(FM_RegUserMsg, FwdRegUserMsg, true)
    }

    unregister_message(MsgIdWeaponList, MsgHookWeaponList)
#endif

    RegForwards()

    CreateCvars()

    AutoExecConfig(true, "reapi_molotov")

    new Path[MAX_RESOURCE_PATH_LENGTH]
    get_localinfo("amxx_configsdir", Path, charsmax(Path))

    if(file_exists(fmt("%s/plugins/reapi_molotov.cfg", Path)))
    {
        server_cmd("exec %s/plugins/reapi_molotov.cfg", Path)
        server_exec()
    }

    AccReadFlags = read_flags(eCvarData[ACCESS])
    SpwReadFlags = read_flags(eCvarData[ACCESS_SPAWN])
    PpReadFlags = read_flags(eCvarData[ACCESS_PICKUP])
    InfReadFlags = read_flags(eCvarData[INFINITE_USAGE_FLAGS])

    if(eCvarData[DMG] == 0.0)
    {
        new Parts[2][16]
        strtok(eCvarData[RANDOM_DAMAGE], Parts[0], charsmax(Parts[]), Parts[1], charsmax(Parts[]), '-')

        rnd_dmg_min = str_to_float(Parts[0])
        rnd_dmg_max = str_to_float(Parts[1])
    }

    if(eCvarData[EFFECT_TEAM_DESIGNATION])
    {
        new RGB[sizeof GlobalColorsEff][6], RGB_RND[sizeof GlobalColorsRndEff][6], SETTINGS[sizeof GlobalSettingsEff][6], i

        if(!eCvarData[EFFECT_CIRCLE_COLOR_MODES])
        {
            parse(eCvarData[EFFECT_COLOR_CT_AND_T], RGB[EFF_CT_R], charsmax(RGB[]), RGB[EFF_CT_G], charsmax(RGB[]), RGB[EFF_CT_B], charsmax(RGB[]), RGB[EFF_T_R], charsmax(RGB[]), RGB[EFF_T_G], charsmax(RGB[]), RGB[EFF_T_B], charsmax(RGB[]))
        }
        else
        {
            parse(eCvarData[EFFECT_COLOR_CT_AND_T_RND], RGB_RND[EFF_CT_R_MIN], charsmax(RGB_RND[]), RGB_RND[EFF_CT_R_MAX], charsmax(RGB_RND[]), RGB_RND[EFF_CT_G_MIN], charsmax(RGB_RND[]), RGB_RND[EFF_CT_G_MAX], charsmax(RGB_RND[]), RGB_RND[EFF_CT_B_MIN], charsmax(RGB_RND[]), RGB_RND[EFF_CT_B_MAX], charsmax(RGB_RND[]), RGB_RND[EFF_T_R_MIN], charsmax(RGB_RND[]), RGB_RND[EFF_T_R_MAX], charsmax(RGB_RND[]), RGB_RND[EFF_T_G_MIN], charsmax(RGB_RND[]), RGB_RND[EFF_T_G_MAX], charsmax(RGB_RND[]), RGB_RND[EFF_T_B_MIN], charsmax(RGB_RND[]), RGB_RND[EFF_T_B_MAX], charsmax(RGB_RND[]))
        }

        while(i < (eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? (sizeof GlobalColorsRndEff) : (sizeof GlobalColorsEff)))
        {
            if(eCvarData[EFFECT_CIRCLE_COLOR_MODES]) GlobalColorsRndEff[i] = str_to_num(RGB_RND[i])
            else GlobalColorsEff[i] = str_to_num(RGB[i])

            i++
        }

        i = 0

        parse(eCvarData[OTHER_EFFECT_SETTINGS], SETTINGS[EFF_TIME_INTERVAL], charsmax(SETTINGS[]), SETTINGS[EFF_LIFE], charsmax(SETTINGS[]), SETTINGS[EFF_WIDTH], charsmax(SETTINGS[]), SETTINGS[EFF_BRIGHTNESS], charsmax(SETTINGS[]))

        while(i < sizeof GlobalSettingsEff)
        {
            GlobalSettingsEff[i] = str_to_num(SETTINGS[i++])
        }
    }
}

public OnConfigsExecuted()
{
    register_cvar("reapi_molotov_version", PLUGIN_VER, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)
}

public plugin_natives()
{
    register_library("reapi_molotov_api")

    register_native("rp_getting_molotov", "native_getting_molotov", 1)
    register_native("rp_molotov_check", "native_molotov_check", 1)
}

RegForwards()
{
    forward_player_takes_damage = CreateMultiForward("rp_player_takes_damage", ET_CONTINUE, FP_CELL, FP_CELL, FP_FLOAT);
    forward_molotov_exploded = CreateMultiForward("rp_molotov_exploded", ET_CONTINUE, FP_CELL);
    forward_player_threw_molotov = CreateMultiForward("rp_player_threw_molotov", ET_CONTINUE, FP_CELL, FP_CELL);
    forward_molotov_dropped = CreateMultiForward("rp_molotov_dropped", ET_CONTINUE, FP_CELL, FP_CELL);
    forward_player_received_molotov = CreateMultiForward("rp_player_received_molotov", ET_CONTINUE, FP_CELL, FP_CELL);
    forward_raising_molotov = CreateMultiForward("rp_raising_molotov", ET_CONTINUE, FP_CELL, FP_CELL);
}

public native_getting_molotov(player_id)
{
    @CmdGettingMolotov(player_id)
}

public native_molotov_check(player_id)
{
    new item = rg_get_player_item(player_id, ITEM_CLASSNAME, GRENADE_SLOT)
    return item != 0 ? 1 : 0
}

#if defined _gamecms5_included
public client_putinserver(id)
{
    new array[1]

    array[0] = 0
    set_task_ex(5.0, "@CheckServices", id, array, sizeof array)

    array[0] = 1
    set_task_ex(5.0, "@CheckServices", id, array, sizeof array)
}

@CheckServices(value[], const PlayerID)
{
    new num = value[0]

    if(cmsapi_get_user_services(PlayerID, "", num == 0 ? GAME_CMS_SERVICES : INFINITE_USAGE_FLAGS_GAMECMS, 0))
    {
        g_Value[num][PlayerID] = true
    }
}
#endif

public client_disconnected(id)
{
    if(CheckPlayerEnt[id] != 0) CheckPlayerEnt[id] = 0

    if(eCvarData[LONG_DELAY_USE])
    {
        remove_task(id+TASK_ID)
        if(CheckLong[id] != 0) CheckLong[id] = 0
    }

    if(CheckCheck[id]) CheckCheck[id] = false

    if(eCvarData[RESTRICTION_ON_USE])
    {
        if(CheckTime[id] > 0) CheckTime[id] = 0
    }

    #if defined _gamecms5_included
    if(g_Value[0][id]) g_Value[0][id] = false
    if(g_Value[1][id]) g_Value[1][id] = false
    #endif

    if(eCvarData[GIVE_LIMIT] > 0) GiveLimit[id] = 0
}

@SrvCmdGettingMolotov(id)
{
    new arg[32]
    read_argv(1, arg, charsmax(arg))

    new player = cmd_target(id, arg, CMDTARGET_ALLOW_SELF | CMDTARGET_ONLY_ALIVE)
    if(!player) return

    GiveMolotov(player)
    amxclient_cmd(player, WEAPON_NEW_NAME)
}

@CmdGettingMolotov(id)
{
    if(!is_user_alive(id)) return

    GiveMolotov(id)
    amxclient_cmd(id, WEAPON_NEW_NAME)
}

#if WEAPON_NEW_ID != WEAPON_GLOCK
@RegUserMsg_Post(const name[])
{
    if(strcmp(name, "WeaponList") == 0)
    {
        MsgIdWeaponList = get_orig_retval()
        MsgHookWeaponList = register_message(MsgIdWeaponList, "@HookWeaponList")
    }
}

@HookWeaponList(const msg_id, const msg_dest, const msg_entity)
{
    enum
    {
        arg_name = 1,
        arg_ammo1,
        arg_ammo1_max,
        arg_ammo2,
        arg_ammo2_max,
        arg_slot,
        arg_position,
        arg_id,
        arg_flags,
    }

    if(msg_dest != MSG_INIT || WeaponIdType:get_msg_arg_int(arg_id) != WEAPON_NEW_ID) return PLUGIN_CONTINUE

    set_msg_arg_string(arg_name,WEAPON_NEW_NAME)
    set_msg_arg_int(arg_ammo1, ARG_BYTE, AMMO_ID)
    set_msg_arg_int(arg_ammo1_max, ARG_BYTE, 1)
    set_msg_arg_int(arg_ammo2, ARG_BYTE, -1)
    set_msg_arg_int(arg_ammo2_max, ARG_BYTE, -1)
    set_msg_arg_int(arg_slot, ARG_BYTE, _:GRENADE_SLOT - 1)
    set_msg_arg_int(arg_position, ARG_BYTE, 4)
    set_msg_arg_int(arg_flags, ARG_BYTE, ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE)

    return PLUGIN_CONTINUE
}
#endif

@CBasePlayer_OnSpawnEquip_Post(const id)
{
    if(eCvarData[GIVE_LIMIT] > 0) GiveLimit[id] = 0

    if(!eCvarData[GET_IN_SPAWN]) return
    set_task_ex(1.0, "@CheckAndGive", id)
}

@CheckAndGive(id)
{
    if(CheckRound < eCvarData[ROUND_LIMIT_ISSUING]) return

    if(get_user_flags(id) & SpwReadFlags == SpwReadFlags)
    {
        if(eCvarData[GIVE_LIMIT] > 0) GiveLimit[id]++
        GiveMolotov(id)
    }
}

@CSGameRules_RestartRound_Pre()
{
    if(get_member_game(m_bCompleteReset))
    {
        CheckRound = 0
    }

    CheckRound++

    if(eCvarData[CHECKING_BUY_ZONE] && eCvarData[TIME_TO_BUY] > 0)
    {
        BuyTime = time() + eCvarData[TIME_TO_BUY]
    }

    if(eCvarData[GIVE_BUY_ZONE] && eCvarData[GIVE_TIME_TO_BUY] > 0)
    {
        GiveTime = time() + eCvarData[GIVE_TIME_TO_BUY]
    }
}

@CmdBuyMolotov(id)
{
    if(!is_user_alive(id)) return

    if(!eCvarData[BUY_MOLOTOV]) return

    if(eCvarData[CHECKING_BUY_ZONE] && !rg_user_in_buyzone(id))
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_BUYZONE_ERROR")
        return
    }

    if(CheckRound < eCvarData[ROUND_LIMIT_BUY])
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_ROUND_LIMIT_BUY", eCvarData[ROUND_LIMIT_BUY] - CheckRound)

        if(eCvarData[PLAY_ERROR_SOUND])
        {
            if(eCvarData[PLAY_ERROR_SOUND_MODE] || eCvarData[PLAY_ERROR_SOUND_MODE] == 4 || eCvarData[PLAY_ERROR_SOUND_MODE] == 5 || eCvarData[PLAY_ERROR_SOUND_MODE] == 6)
            {
                client_cmd(id, fmt("spk %s", eCvarData[ERROR_SOUND_PATH_AND_NAME]))
            }
        }

        return
    }

    if(eCvarData[CHECKING_BUY_ZONE] && eCvarData[TIME_TO_BUY] > 0 && BuyTime < time())
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_TIME_TO_BUY_ERROR")
        return
    }

    new item = rg_get_player_item(id, ITEM_CLASSNAME, GRENADE_SLOT)

    if(item != 0)
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_BUY_ERROR")
        return
    }

    if(get_member(id, m_iAccount) < eCvarData[MOLOTOV_COST])
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_COST_ERROR", eCvarData[MOLOTOV_COST])

        if(eCvarData[PLAY_ERROR_SOUND])
        {
            if(eCvarData[PLAY_ERROR_SOUND_MODE] == 3 || eCvarData[PLAY_ERROR_SOUND_MODE] == 4 || eCvarData[PLAY_ERROR_SOUND_MODE] == 6 || eCvarData[PLAY_ERROR_SOUND_MODE] == 7)
            {
                client_cmd(id, fmt("spk %s", eCvarData[ERROR_SOUND_PATH_AND_NAME]))
            }
        }

        return
    }

    rg_add_account(id, -eCvarData[MOLOTOV_COST])
    GiveMolotov(id)
    amxclient_cmd(id, WEAPON_NEW_NAME)
}

@CmdGiveMolotov(id)
{
    if(!is_user_alive(id)) return
    GiveMolotovHandler(id, 2)
}

GiveMolotovHandler(id, value)
{
    new bool:Verification[MAX_PLAYERS+1] = false

    #if defined _gamecms5_included
    if(g_Value[0][id]) Verification[id] = true
    #endif
    if(get_user_flags(id) & AccReadFlags == AccReadFlags) Verification[id] = true

    if(!Verification[id]) return

    if(eCvarData[GIVE_BUY_ZONE] && !rg_user_in_buyzone(id))
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_BUYZONE_ERROR")
        return
    }

    if(CheckRound < eCvarData[ROUND_LIMIT_ISSUING])
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_ROUND_LIMIT_ISSUING", eCvarData[ROUND_LIMIT_ISSUING] - CheckRound)

        if(eCvarData[PLAY_ERROR_SOUND])
        {
            if(eCvarData[PLAY_ERROR_SOUND_MODE] == 2 || eCvarData[PLAY_ERROR_SOUND_MODE] == 4 || eCvarData[PLAY_ERROR_SOUND_MODE] == 5 || eCvarData[PLAY_ERROR_SOUND_MODE] == 7)
            {
                client_cmd(id, fmt("spk %s", eCvarData[ERROR_SOUND_PATH_AND_NAME]))
            }
        }

        return
    }

    if(eCvarData[GIVE_BUY_ZONE] && eCvarData[GIVE_TIME_TO_BUY] > 0 && GiveTime < time())
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_GIVE_TIME_TO_BUY_ERROR")
        return
    }

    new item = rg_get_player_item(id, ITEM_CLASSNAME, GRENADE_SLOT)

    if(item != 0)
    {
        client_print(id, print_center, "%l", "REAPI_MOLOTOV_BUY_ERROR")
        return
    }

    if(eCvarData[RESTRICTION_ON_USE])
    {
        if(CheckTimeHandler(id, 1)) return
    }

    if(eCvarData[GIVE_LIMIT] > 0)
    {
        if(GiveLimit[id] > eCvarData[GIVE_LIMIT])
        {
            client_print(id, print_center, "%l", "REAPI_MOLOTOV_GIVE_LIMIT_ERROR", eCvarData[GIVE_LIMIT])
            return
        }
        else
        {
            GiveLimit[id]++
        }
    }

    GiveMolotov(id)

    if(value == 2) amxclient_cmd(id, WEAPON_NEW_NAME)
}

CheckTimeHandler(id, value)
{
    new bool:Verification[MAX_PLAYERS+1] = false

    #if defined _gamecms5_included
    if(g_Value[1][id]) Verification[id] = true
    #endif
    if(get_user_flags(id) & InfReadFlags == InfReadFlags) Verification[id] = true

    if(!Verification[id])
    {
        switch(value)
        {
            case 1:
            {
                if(CheckTime[id] > time())
                {
                    client_print_color(id, print_team_default, "%l", "REAPI_MOLOTOV_STOP_USE", CheckTime[id] - time())
                    return 1
                }
            }
            case 2: CheckTime[id] = eCvarData[TIME_LIMIT_ON_USAGE] + time()
        }
    }

    return 0
}

@CmdSelect(const id)
{
    if(!is_user_alive(id)) return PLUGIN_HANDLED

    new item = rg_get_player_item(id, ITEM_CLASSNAME, GRENADE_SLOT)

    if(item != 0 && get_member(id, m_pActiveItem) != item) rg_switch_weapon(id, item)

    return PLUGIN_HANDLED
}

@CSGameRules_CleanUpMap_Post()
{
    new ent = rg_find_ent_by_class(NULLENT, GRENADE_CLASSNAME, false)

    while(ent > 0)
    {
        destroyNade(ent)
        ent = rg_find_ent_by_class(ent, GRENADE_CLASSNAME, false)
    }

    ent = rg_find_ent_by_class(NULLENT, MOLOTOV_FIRE_CLASSNAME, false)

    while(ent > 0)
    {
        destroyNade(ent)
        ent = rg_find_ent_by_class(ent, MOLOTOV_FIRE_CLASSNAME, false)
    }
}

@CBasePlayer_GiveAmmo_Pre(const id, const amount, const name[])
{
    if(strcmp(name, AMMO_NAME) != 0) return HC_CONTINUE

    giveAmmo(id, amount, AMMO_ID, 1)
    SetHookChainReturn(ATYPE_INTEGER, AMMO_ID)

    return HC_SUPERCEDE
}

@CBasePlayerWeapon_DefaultDeploy_Pre(const item, const szViewModel[], const szWeaponModel[], const iAnim, const szAnimExt[], const skiplocal)
{
    if(FClassnameIs(item, ITEM_CLASSNAME))
    {
        new Buffer[64]

        ArrayGetString(SaveModels, 0, Buffer, charsmax(Buffer))
        SetHookChainArg(2, ATYPE_STRING, Buffer)

        Buffer[0] = EOS

        ArrayGetString(SaveModels, 1, Buffer, charsmax(Buffer))
        SetHookChainArg(3, ATYPE_STRING, Buffer)

        SetHookChainArg(4, ATYPE_INTEGER, MOLOTOV_ANIM_DRAW)
    }

    new WeaponIdType:wid = WeaponIdType:rg_get_iteminfo(item, ItemInfo_iId)
    if(wid != WEAPON_ID && wid != WEAPON_FAKE_ID) return HC_CONTINUE

    new lastItem = get_member(get_member(item, m_pPlayer), m_pLastItem)
    if(is_nullent(lastItem) || item == lastItem) return HC_CONTINUE

    if(WeaponIdType:rg_get_iteminfo(lastItem, ItemInfo_iId) == WEAPON_ID)
    {
        SetHookChainArg(6, ATYPE_INTEGER, 0)
    }

    return HC_CONTINUE
}

@Item_Deploy_Post(const item)
{
    if(WeaponIdType:rg_get_iteminfo(item, ItemInfo_iId) == WEAPON_FAKE_ID)
    {
        rg_set_iteminfo(item, ItemInfo_iId, WEAPON_ID)
    }

    new other = get_member(get_member(item, m_pPlayer), m_rgpPlayerItems, GRENADE_SLOT)

    while(!is_nullent(other))
    {
        if(item != other && WeaponIdType:rg_get_iteminfo(other, ItemInfo_iId) == WEAPON_ID)
        {
            rg_set_iteminfo(other, ItemInfo_iId, WEAPON_FAKE_ID)
        }

        other = get_member(other, m_pNext)
    }
}

@Item_Holster_Post(const item)
{
    new other = get_member(get_member(item, m_pPlayer), m_rgpPlayerItems, GRENADE_SLOT)

    while(!is_nullent(other))
    {
        if(item != other && WeaponIdType:rg_get_iteminfo(other, ItemInfo_iId) == WEAPON_FAKE_ID)
        {
            rg_set_iteminfo(other, ItemInfo_iId, WEAPON_ID)
        }

        other = get_member(other, m_pNext)
    }

    if(CheckCheck[get_member(item, m_pPlayer)])
    {
        SoundAndCheckLong(get_member(item, m_pPlayer), 1)
    }

    CheckCheck[get_member(item, m_pPlayer)] = false

    if(FClassnameIs(item, ITEM_CLASSNAME))
    {
        new iMuzzleFlash = get_member(item, m_Weapon_iFamasShotsFired)

        if(!is_nullent(iMuzzleFlash))
        {
            set_entvar(iMuzzleFlash, var_flags, FL_KILLME)

            set_member(get_member(item, m_pPlayer), m_flNextAttack, 0.5)
            set_member(item, m_flStartThrow, 0.0)
            set_member(item, m_flReleaseThrow, 1.0)
            set_member(item, m_Weapon_iFamasShotsFired, NULLENT)
        }
    }
}

@Molotov_PrimaryAttack_Pre(iEntity)
{
    if(is_nullent(iEntity)) return HAM_IGNORED
    if(!FClassnameIs(iEntity, ITEM_CLASSNAME)) return HAM_IGNORED

    new iPlayer = get_member(iEntity, m_pPlayer)

    new AmmoCount = get_member(iPlayer, m_rgAmmo, AMMO_ID)
    if(!AmmoCount) return HAM_IGNORED

    if(!CheckCheck[iPlayer]) SoundAndCheckLong(iPlayer)

    if(!Float: get_member(iEntity, m_flStartThrow))
    {
        set_entvar(iPlayer, var_weaponanim, MOLOTOV_ANIM_PULLPIN)
        set_member(iEntity, m_flReleaseThrow, 0.0)
        set_member(iEntity, m_flStartThrow, get_gametime())
        set_member(iEntity, m_Weapon_flTimeWeaponIdle, 0.5)

        return HAM_SUPERCEDE
    }

    CreateMuzzleFlash(iEntity, iPlayer)

    return HC_SUPERCEDE
}

@Molotov_SecondaryAttack_Pre(iEntity)
{
    if(is_nullent(iEntity)) return 0

    if(!FClassnameIs(iEntity, ITEM_CLASSNAME)) return HAM_SUPERCEDE

    return HAM_IGNORED
}

SoundAndCheckLong(iPlayer, value=0)
{
    new Buffer[64]
    ArrayGetString(SaveSound, 4, Buffer, charsmax(Buffer))

    rh_emit_sound2(iPlayer, 0, CHAN_STATIC, Buffer, VOL_NORM, ATTN_NORM, value == 0 ? 0 : SND_STOP, PITCH_HIGH)

    if(value == 0)
    {
        if(eCvarData[LONG_DELAY_USE])
        {
            remove_task(TASK_ID+iPlayer)
            CheckLong[iPlayer] = 0

            set_task_ex(eCvarData[LONG_DELAY_TIME], "@LongDelay", TASK_ID + iPlayer)
        }

        CheckCheck[iPlayer] = true
    }
}

@CBasePlayer_ThrowGrenade_Pre(const id, const item, const Float:vecSrc[3], const Float:vecThrow[3], const Float:time, const usEvent)
{
    if(!is_user_alive(id)) return HC_CONTINUE

    if(!FClassnameIs(item, ITEM_CLASSNAME)) return HC_CONTINUE

    if(eCvarData[RESTRICTION_ON_USE])
    {
        CheckTimeHandler(id, 2)
    }

    new grenade = throwNade(id, vecSrc, vecThrow, time)

    new result
    ExecuteForward(forward_player_threw_molotov, result, id, grenade);

    SetHookChainReturn(ATYPE_INTEGER, grenade)

    CheckPlayerEnt[id] = 0

    CheckCheck[id] = false

    SoundAndCheckLong(id, 1)

    if(eCvarData[LONG_DELAY_USE])
    {
        remove_task(id+TASK_ID)
        CheckLong[id] = 0
    }

    new iMuzzleFlash = get_member(item, m_Weapon_iFamasShotsFired)

    if(!is_nullent(iMuzzleFlash))
    {
        set_entvar(iMuzzleFlash, var_flags, FL_KILLME)

        set_member(item, m_flStartThrow, 0.0)
        set_member(item, m_Weapon_iFamasShotsFired, NULLENT)
        set_member(item, m_Weapon_flNextPrimaryAttack, 0.5)
        set_member(item, m_Weapon_flTimeWeaponIdle, 0.75)
    }

    return HC_SUPERCEDE
}

@GrenadeTouch(const iEntity, const iOther)
{
    if(is_nullent(iEntity)) return

    if(!FClassnameIs(iEntity, GRENADE_CLASSNAME)) return

    if(eCvarData[TIME_OF_DETONATE] == 0.0)
    {
        Molotov_Detonate(iEntity)
        return
    }

    new Float:flFraction

    new Float:vecOffset[6][3] =
    {
        { 0.0, 0.0, -1.0 }, { 0.0, 0.0, 1.0 }, { -1.0, 0.0, 0.0 },
        { 1.0, 0.0, 0.0 }, { 0.0, -1.0, 0.0 }, { 0.0, 1.0, 0.0 }
    }

    new Float:vecEnd[3]
    new Float:vecOrigin[3]
    new Float:vecPlaneNormal[3]

    get_entvar(iEntity, var_origin, vecOrigin)

    for(new i = 0; i < 6; i++)
    {
        vecEnd[0] = vecOrigin[0] + vecOffset[i][0]
        vecEnd[1] = vecOrigin[1] + vecOffset[i][1]
        vecEnd[2] = vecOrigin[2] + vecOffset[i][2]

        engfunc(EngFunc_TraceLine, vecOrigin, vecEnd, IGNORE_MONSTERS, iEntity, 0)

        get_tr2(0, TR_flFraction, flFraction)

        if(flFraction >= 1.0) continue

        get_tr2(0, TR_vecPlaneNormal, vecPlaneNormal)

        if(vecPlaneNormal[2] >= 0.5)
        {
            set_entvar(iEntity, var_dmgtime, 0.0)
            set_entvar(iEntity, var_nextthink, get_gametime() + 0.001)
        }
        else
        {
            if(task_exists(iEntity+TASK_ID2))
            {
                new Buffer[2][64]
                ArrayGetString(SaveSound, 2, Buffer[0], charsmax(Buffer[]))
                ArrayGetString(SaveSound, 3, Buffer[1], charsmax(Buffer[]))

                rh_emit_sound2(iEntity, 0, CHAN_VOICE, random_num(0, 1) ? Buffer[0] : Buffer[1])
                break
            }
        }
    }
}

@GrenadeThink(const iEntity)
{
    if(is_nullent(iEntity)) return

    new Float:vecOrigin[3]
    get_entvar(iEntity, var_origin, vecOrigin)

    if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER)
    {
        TE_SetupSmoke(vecOrigin, Float:{ 0.0, 0.0, 0.0 }, g_iModelIndex[3], 7, 15)
        set_entvar(iEntity, var_flags, FL_KILLME)

        return
    }

    if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_SKY)
    {
        set_entvar(iEntity, var_flags, FL_KILLME)
        return
    }

    set_entvar(iEntity, var_nextthink, get_gametime() + 0.1)

    if(Float:get_entvar(iEntity, var_dmgtime) > get_gametime()) return

    if(task_exists(iEntity)) return

    Molotov_Detonate(iEntity)
}

GiveMolotov(const id)
{
    new item = rg_get_player_item(id, ITEM_CLASSNAME, GRENADE_SLOT)

    if(item != 0)
    {
        giveAmmo(id, 1, AMMO_ID, 1)
        return item
    }

    item = rg_create_entity(WEAPON_NAME, false)

    if(is_nullent(item))
    {
        return NULLENT
    }

    new Float:origin[3]

    get_entvar(id, var_origin, origin)
    set_entvar(item, var_origin, origin)
    set_entvar(item, var_spawnflags, get_entvar(item, var_spawnflags) | SF_NORESPAWN)

    set_member(item, m_Weapon_iPrimaryAmmoType, AMMO_ID)
    set_member(item, m_Weapon_iSecondaryAmmoType, -1)
    set_member(item, m_Weapon_iFamasShotsFired, NULLENT)

    set_entvar(item, var_classname, ITEM_CLASSNAME)

    dllfunc(DLLFunc_Spawn, item)

    set_member(item, m_iId, WEAPON_NEW_ID)

    rg_set_iteminfo(item, ItemInfo_pszName, WEAPON_NEW_NAME)
    rg_set_iteminfo(item, ItemInfo_pszAmmo1, AMMO_NAME)
    rg_set_iteminfo(item, ItemInfo_iMaxAmmo1, 1)
    rg_set_iteminfo(item, ItemInfo_iId, WEAPON_FAKE_ID)
    rg_set_iteminfo(item, ItemInfo_iPosition, 5)
    rg_set_iteminfo(item, ItemInfo_iWeight, 1)

    dllfunc(DLLFunc_Touch, item, id)

    if(get_entvar(item, var_owner) != id)
    {
        set_entvar(item, var_flags, FL_KILLME)
        return NULLENT
    }

    CheckPlayerEnt[id] = item

    CheckCheck[id] = false

    new Buffer[64]
    ArrayGetString(SaveSound, 5, Buffer, charsmax(Buffer))

    rh_emit_sound2(id, 0, CHAN_ITEM, Buffer)
    set_task_ex(0.3, "@ammosound", id) //для возможности своего звука выдачи патрона.

    new result
    ExecuteForward(forward_player_received_molotov, result, id, item);

    return item
}

giveAmmo(const id, const amount, const ammo, const max)
{
    if(get_entvar(id, var_flags) & FL_SPECTATOR) return

    new count = get_member(id, m_rgAmmo, ammo)
    new add = min(amount, max - count)

    if(add < 1) return

    set_member(id, m_rgAmmo, count + add, ammo)

    emessage_begin(MSG_ONE, MsgIdAmmoPickup, .player = id)
    ewrite_byte(ammo)
    ewrite_byte(add)
    emessage_end()
}

throwNade(const id, const Float:vecSrc[3], const Float:vecThrow[3], const Float:time)
{
    new grenade = rg_create_entity("info_target", false)

    if(is_nullent(grenade)) return 0

    set_entvar(grenade, var_classname, GRENADE_CLASSNAME)

    set_entvar(grenade, var_movetype, MOVETYPE_BOUNCE)
    set_entvar(grenade, var_solid, SOLID_BBOX)

    engfunc(EngFunc_SetOrigin, grenade, vecSrc)

    new Float:angles[3]

    get_entvar(id, var_angles, angles)
    set_entvar(grenade, var_angles, angles)
    set_entvar(grenade, var_owner, id)

    if(time < 0.1)
    {
        set_entvar(grenade, var_nextthink, get_gametime())
        set_entvar(grenade, var_velocity, Float:{0.0, 0.0, 0.0})
    }
    else
    {
        set_entvar(grenade, var_nextthink, get_gametime() + time)
        set_entvar(grenade, var_velocity, vecThrow)
    }

    set_entvar(grenade, var_sequence, random_num(1, 6))
    set_entvar(grenade, var_framerate, 1.0)
    set_entvar(grenade, var_gravity, 0.5)
    set_entvar(grenade, var_friction, 0.8)

    new Buffer[64]
    ArrayGetString(SaveModels, 2, Buffer, charsmax(Buffer))

    engfunc(EngFunc_SetModel, grenade, Buffer)

    if(eCvarData[LONG_DELAY_USE])
    {
        if(CheckLong[id] == 1)
        {
            Molotov_Detonate(grenade)
            CheckLong[id] = 0
            CheckPlayerEnt[id] = 0
            if(eCvarData[LONG_DELAY_KILL]) user_kill(id, 0)

            return 0
        }
    }

    set_entvar(grenade, var_dmgtime, get_gametime() + time)

    if(eCvarData[TIME_OF_DETONATE] > 0.0)
    {
        set_task_ex(eCvarData[TIME_OF_DETONATE], "@Dummy1", grenade)
        set_task_ex(eCvarData[IMPACT_SOUND_TIME], "@Dummy2", grenade + TASK_ID2)
    }

    SetTouch(grenade, "@GrenadeTouch")
    SetThink(grenade, "@GrenadeThink")

    return grenade
}

Molotov_Detonate(iEntity)
{
    if(is_nullent(iEntity)) return

    new Float:flFraction, Float:vecEnd[3], Float:vecOrigin[3]

    get_entvar(iEntity, var_origin, vecOrigin)

    if(engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER)
    {
        TE_SetupSmoke(vecOrigin, Float:{ 0.0, 0.0, 0.0 }, g_iModelIndex[3], 7, 15)
        set_entvar(iEntity, var_flags, FL_KILLME)

        return
    }

    vecEnd = vecOrigin
    vecEnd[2] -= 64.0

    engfunc(EngFunc_TraceLine, vecOrigin, vecEnd, IGNORE_MONSTERS, iEntity, 0)
    get_tr2(0, TR_flFraction, flFraction)

    new Buffer[64]

    if(flFraction >= 1.0)
    {
        TE_SetupExplosion(vecOrigin, Float:{ 0.0, 0.0, 20.0 }, g_iModelIndex[1], 20, 15, TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES)
        TE_SetupExplosion(vecOrigin, Float:{ 0.0, 0.0, 20.0 }, g_iModelIndex[0], 20, 15, TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES)

        ArrayGetString(SaveSound, 0, Buffer, charsmax(Buffer))
        rh_emit_sound2(iEntity, 0, CHAN_WEAPON, Buffer, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)

        destroyNade(iEntity)
        return
    }

    new iOwner = get_entvar(iEntity, var_owner)

    new Float:vecEndPos[3]
    new Float:vecPlaneNormal[3]

    get_tr2(0, TR_vecEndPos, vecEndPos)
    get_tr2(0, TR_vecPlaneNormal, vecPlaneNormal)

    Molotov_CreateDebris(iOwner, vecEndPos)

    Buffer[0] = EOS

    ArrayGetString(SaveSound, 1, Buffer, charsmax(Buffer))

    rh_emit_sound2(iEntity, 0, CHAN_WEAPON, Buffer, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)

    new array[1]
    set_task_ex(1.0, "@FireSound", iEntity + TASK_ID4, array, sizeof array)

    array[0] = 1
    set_task_ex(eCvarData[FIRETIME], "@FireSound", iEntity + TASK_ID4, array, sizeof array)

    new result
    ExecuteForward(forward_molotov_exploded, result, iOwner);

    destroyNade(iEntity)

    if(eCvarData[EFFECT_TEAM_DESIGNATION])
    {
        new SavingArray[3]

        SavingArray[0] = floatround(vecEndPos[0])
        SavingArray[1] = floatround(vecEndPos[1])
        SavingArray[2] = floatround(vecEndPos[2])

        set_task_ex(float(GlobalSettingsEff[EFF_TIME_INTERVAL]), "@CircleEffect", iOwner, SavingArray, sizeof SavingArray, SetTask_RepeatTimes, (floatround(eCvarData[FIRETIME]) / GlobalSettingsEff[EFF_TIME_INTERVAL]))
    }
}

@FireSound(value[], id)
{
    new num = value[0]
    new iEntity = id - TASK_ID4

    new Buffer[64]
    ArrayGetString(SaveSound, 7, Buffer, charsmax(Buffer))

    rh_emit_sound2(iEntity, 0, CHAN_WEAPON, Buffer, VOL_NORM, ATTN_NORM, num == 0 ? 0 : SND_STOP, PITCH_NORM)
}

@LongDelay(id)
{
    new player_id = id - TASK_ID
    CheckLong[player_id] = 1
}

@FireMolotov_Think_Post(iEntity)
{
    if(is_nullent(iEntity)) return

    if(get_entvar(iEntity, var_chain) != OBJECT_MOLOTOV_FIRE) return

    new Float:flCurTime = get_gametime()

    new Float:vecOrigin[3]
    get_entvar(iEntity, var_origin, vecOrigin)

    if(eCvarData[EXTINGUISHING])
    {
        if(CheckGrenade(iEntity))
        {
            set_task_ex(eCvarData[EXTINGUISHING_TIME], "@KillFireEnt", iEntity)
        }
    }

    if(Float:get_entvar(iEntity, var_teleport_time) <= flCurTime)
    {
        TE_SetupSmoke(vecOrigin, Float:{ 0.0, 0.0, 0.0 }, g_iModelIndex[3], 7, 15)
        set_entvar(iEntity, var_flags, FL_KILLME)
    }

    new iOwner = get_entvar(iEntity, var_owner)

    if(!is_user_connected(iOwner)) return

    if(flCurTime2[iOwner] == 0.0)
    {
        flCurTime2[iOwner] = get_gametime() + eCvarData[DMG_TICK]
    }

    if(get_gametime() >= flCurTime2[iOwner])
    {
        static iVictim = -1

        while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, vecOrigin, eCvarData[RADIUS])))
        {
            if(!is_user_alive(iVictim)) continue

            if(!eCvarData[DMG_TM])
            {
                if(iOwner != iVictim && get_member(iOwner, m_iTeam) == get_member(iVictim, m_iTeam)) continue
            }

            new Float:Damage
            Damage = eCvarData[DMG] == 0.0 ? random_float(rnd_dmg_min, rnd_dmg_max) : eCvarData[DMG]

            ExecuteHamB(Ham_TakeDamage, iVictim, iEntity, iOwner, Damage, (eCvarData[DAMAGE_FLAGS] ? DMG_BURN : DMG_GENERIC))

            new result
            ExecuteForward(forward_player_takes_damage, result, iOwner, iVictim, Damage)

            rh_emit_sound2(iVictim, 0, CHAN_STATIC, "player/pl_pain2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
        }

        flCurTime2[iOwner] = 0.0
    }

    if(Float:get_entvar(iEntity, var_dmgtime) <= flCurTime)
    {
        if(pev_valid(iEntity)) set_entvar(iEntity, var_dmgtime, flCurTime + eCvarData[ANIM_TICK])
        TE_SetupExplosion(vecOrigin, Float:{ 0.0, 0.0, 24.0 }, g_iModelIndex[2], 8, 20, TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES)
    }

    new iFireNum = get_entvar(iEntity, var_iuser1)

    if(iFireNum < 15)
    {
        new Float:flFraction, Float:vecStart[3], Float:vecEnd[3], Float:vecAngles[3], Float:vecViewForward[3], Float:vecPlaneNormal[3]

        get_entvar(iEntity, var_vuser1, vecPlaneNormal)

        vecAngles[0] = random_float(-45.0, -135.0)
        vecAngles[1] = random_float(0.0, 360.0)

        engfunc(EngFunc_MakeVectors, vecAngles)
        global_get(glb_v_forward, vecViewForward)

        for(new i = 0; i < 3; i++)
        {
            vecStart[i] = vecOrigin[i] + vecPlaneNormal[i] * 64.0
            vecEnd[i] = vecStart[i] + vecViewForward[i] * 128.0
        }

        engfunc(EngFunc_TraceLine, vecStart, vecEnd, IGNORE_MONSTERS, iEntity, 0)

        get_tr2(0, TR_flFraction, flFraction)
        get_tr2(0, TR_vecEndPos, vecEnd)
        get_tr2(0, TR_vecPlaneNormal, vecPlaneNormal)

        if(flFraction >= 1.0 || vecPlaneNormal[2] == -1.0)
        {
            set_entvar(iEntity, var_iuser1, iFireNum + 1)
            Molotov_CreateDebris(iEntity, vecEnd)
        }
    }
}

Molotov_CreateDebris(iOwner, Float:vecOrigin[3])
{
    if(is_nullent(iOwner)) return

    new Float:flFraction, Float:flCurTime = get_gametime(), Float:vecEndPos[3], Float:vecPlaneNormal[3], Float:vecAngles[3]

    vecEndPos = vecOrigin
    vecEndPos[2] -= 256.0

    engfunc(EngFunc_TraceLine, vecOrigin, vecEndPos, IGNORE_MONSTERS, iOwner, 0)
    get_tr2(0, TR_flFraction, flFraction)

    if(flFraction >= 1.0) return

    get_tr2(0, TR_vecEndPos, vecEndPos)
    get_tr2(0, TR_vecPlaneNormal, vecPlaneNormal)

    engfunc(EngFunc_VecToAngles, vecPlaneNormal, vecAngles)

    for(new i = 0; i < 3; i++)
    {
        vecOrigin[i] = vecEndPos[i] + vecPlaneNormal[i]
    }

    new iFire = rg_create_entity("env_sprite")

    if(!SetEntvarFireHandler(iFire, 1, vecOrigin, flCurTime, iOwner)) return

    if(iOwner < MaxClients)
    {
        set_entvar(iFire, var_vuser1, vecPlaneNormal)
    }
    else
    {
        if(!SetEntvarFireHandler(iFire, 2, vecOrigin, flCurTime, iOwner)) return
    }
}

SetEntvarFireHandler(iFire, value, Float:vecOrigin[3] = { 0.0, 0.0, 0.0 }, Float:flCurTime, iOwner)
{
    if(is_nullent(iFire) || engfunc(EngFunc_PointContents, vecOrigin) == CONTENTS_WATER) return 0

    if(value == 2) vecOrigin[2] += 24.0

    set_entvar(iFire, var_classname, MOLOTOV_FIRE_CLASSNAME)
    set_entvar(iFire, var_chain, OBJECT_MOLOTOV_FIRE)
    set_entvar(iFire, var_origin, vecOrigin)

    new Buffer[64]
    ArrayGetString(SaveSprites, value == 1 ? 1 : 0, Buffer, charsmax(Buffer))

    set_entvar(iFire, var_model, Buffer)
    set_entvar(iFire, var_spawnflags, SF_SPRITE_STARTON)
    set_entvar(iFire, var_teleport_time, flCurTime + eCvarData[FIRETIME])
    set_entvar(iFire, var_owner, iOwner)
    set_entvar(iFire, var_rendermode, kRenderTransAdd)
    set_entvar(iFire, var_renderamt, 255.0)
    set_entvar(iFire, var_framerate, value == 1 ? 10.0 : 30.0)
    set_entvar(iFire, var_scale, value == 1 ? 0.5 : 0.4)

    dllfunc(DLLFunc_Spawn, iFire)

    return 1
}

TE_SetupExplosion(Float:vecOrigin[3], Float:vecOriginOffset[3] = { 0.0, 0.0, 0.0 }, isModelIndex, iScale, iFrameRate, iFlags)
{
    message_begin_f(MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0)
    write_byte(TE_EXPLOSION)
    write_coord_f(vecOrigin[0] + vecOriginOffset[0])
    write_coord_f(vecOrigin[1] + vecOriginOffset[1])
    write_coord_f(vecOrigin[2] + vecOriginOffset[2])
    write_short(isModelIndex)
    write_byte(iScale)
    write_byte(iFrameRate)
    write_byte(iFlags)
    message_end()
}

TE_SetupSmoke(Float:vecOrigin[3], Float:vecOriginOffset[3] = { 0.0, 0.0, 0.0 }, isModelIndex, iScale, iFrameRate)
{
    message_begin_f(MSG_PVS, SVC_TEMPENTITY, vecOrigin, 0)
    write_byte(TE_SMOKE)
    write_coord_f(vecOrigin[0] + vecOriginOffset[0])
    write_coord_f(vecOrigin[1] + vecOriginOffset[1])
    write_coord_f(vecOrigin[2] + vecOriginOffset[2])
    write_short(isModelIndex)
    write_byte(iScale)
    write_byte(iFrameRate)
    message_end()
}

destroyNade(const grenade)
{
    SetTouch(grenade, "")
    SetThink(grenade, "")

    set_entvar(grenade, var_flags, FL_KILLME)
}

@CBasePlayer_Killed_Post(iVictim, iAttacker, iGib)
{
    if(eCvarData[USE_PICKUP])
    {
        if(CheckPlayerEnt[iVictim] != 0)
        {
            CheckPlayerEnt[iVictim] = 0
            Molotov_DropAndCreateItem(iVictim)
        }
    }
}

Molotov_DropAndCreateItem(iPlayer)
{
    if(!is_user_connected(iPlayer)) return

    new iEntity = rg_create_entity("info_target", false)

    if(is_nullent(iEntity)) return

    new Float:vecOrigin[3], Float:vecVelocity[3]

    ExecuteHam(Ham_Player_GetGunPosition, iPlayer, vecOrigin)

    vecVelocity[0] = random_float(-45.0, 45.0)
    vecVelocity[1] = random_float(-45.0, 45.0)

    new Buffer[64]
    ArrayGetString(SaveModels, 2, Buffer, charsmax(Buffer))

    engfunc(EngFunc_SetModel, iEntity, Buffer)
    engfunc(EngFunc_SetOrigin, iEntity, vecOrigin)

    set_entvar(iEntity, var_classname, GRENADE_CLASSNAME)
    set_entvar(iEntity, var_velocity, vecVelocity)
    set_entvar(iEntity, var_movetype, MOVETYPE_TOSS)
    set_entvar(iEntity, var_solid, SOLID_TRIGGER)

    new result
    ExecuteForward(forward_molotov_dropped, result, iPlayer, iEntity);

    SetTouch(iEntity, "@ItemMolotov_Touch")
}

@ItemMolotov_Touch(iEntity, iOther)
{
    if(is_nullent(iEntity) || is_nullent(iOther)) return

    if(!ExecuteHam(Ham_IsPlayer, iOther)) return

    if(CheckPlayerEnt[iOther] != 0) return

    if(get_user_flags(iOther) & PpReadFlags == PpReadFlags || !PpReadFlags)
    {
        new Item = GiveMolotov(iOther)

        new result
        ExecuteForward(forward_raising_molotov, result, iOther, Item)

        SetTouch(iEntity, "")
        set_entvar(iEntity, var_flags, FL_KILLME)
    }
}

@ammosound(id)
{
    new Buffer[64]
    ArrayGetString(SaveSound, 6, Buffer, charsmax(Buffer))

    rh_emit_sound2(id, 0, CHAN_ITEM, Buffer)
}

@KillFireEnt(ent)
{
    if(!pev_valid(ent)) return

    new Float:Origin[3]
    get_entvar(ent, var_origin, Origin)

    TE_SetupSmoke(Origin, Float:{ 0.0, 0.0, 0.0 }, g_iModelIndex[3], 7, 15)
    set_entvar(ent, var_flags, FL_KILLME)
}

CheckGrenade(Entity)
{
    if(is_nullent(Entity) || !pev_valid(Entity)) return 0

    static entList[10]
    new foundGrenades = fm_find_sphere_class(Entity, "grenade", eCvarData[RADIUS] * eCvarData[RADIUS_MULTIPLIER], entList, charsmax(entList))

    if(!foundGrenades) return 0

    new entModel[64]

    for(new i; i < foundGrenades; i++)
    {
        if(is_nullent(entList[i])) return 0

        entModel[0] = EOS
        get_entvar(entList[i], var_model, entModel, charsmax(entModel))

        if(GrenadeHandler(entModel, entList[i])) return 1
    }

    return 0
}

@grenade_fix_velosity(ent)
{
    if(is_nullent(ent)) return
    set_entvar(ent, var_velocity, Float:{0.0, 0.0, 0.0})
}

GrenadeHandler(model[], ent)
{
    if(is_nullent(ent)) return 0

    new bool:check

    for(new i, Buffer[64]; i < ArraySize(SaveGrenadeNames); i++)
    {
        Buffer[0] = EOS
        ArrayGetString(SaveGrenadeNames, i, Buffer, charsmax(Buffer))

        if(contain(model, Buffer) != -1)
        {
            new Float:dmgTime

            get_entvar(ent, var_dmgtime, dmgTime)
            set_entvar(ent, var_dmgtime, floatmax(0.0, dmgTime - 2.0))

            set_task_ex(dmgTime, "@grenade_fix_velosity", ent)
            set_entvar(ent, var_nextthink, get_gametime() + 0.01)

            check = true
        }
    }

    return !check ? 0 : 1
}

fm_find_sphere_class(OldEnt, OldClass[], Float:radius, entList[], maxents)
{
    if(is_nullent(OldEnt) || !pev_valid(OldEnt)) return 0

    new Float:Origin[3]
    get_entvar(OldEnt, var_origin, Origin)

    new i

    for(new ent = engfunc(EngFunc_FindEntityInSphere, OldEnt, Origin, radius), Class[32]; ent > 0; ent = engfunc(EngFunc_FindEntityInSphere, ent, Origin, radius))
    {
        if(is_nullent(ent)) continue
        if(ent == OldEnt) continue
        if(i >= maxents) break

        Class[0] = EOS
        get_entvar(ent, var_classname, Class, charsmax(Class))

        if(equal(OldClass, Class)) entList[i++] = ent
    }

    return i
}

CreateMuzzleFlash(iEntity, iPlayer)
{
    if(is_nullent(iEntity)) return
    if(get_member(iEntity, m_Weapon_iFamasShotsFired) != NULLENT || Float: get_member(iEntity, m_flStartThrow) + 0.5 > get_gametime()) return

    new iMuzzleFlash = rg_create_entity("env_sprite", true)

    if(is_nullent(iMuzzleFlash)) return

    new Buffer[64]
    ArrayGetString(SaveSprites, 2, Buffer, charsmax(Buffer))

    set_entvar(iMuzzleFlash, var_model, Buffer)
    set_entvar(iMuzzleFlash, var_spawnflags, SF_SPRITE_STARTON)
    set_entvar(iMuzzleFlash, var_rendermode, kRenderTransAdd)
    set_entvar(iMuzzleFlash, var_renderamt, 200.0)
    set_entvar(iMuzzleFlash, var_framerate, 25.0)
    set_entvar(iMuzzleFlash, var_scale, eCvarData[FIRE_EFF])
    set_entvar(iMuzzleFlash, var_owner, iPlayer)
    set_entvar(iMuzzleFlash, var_aiment, iPlayer)
    set_entvar(iMuzzleFlash, var_body, 3)

    dllfunc(DLLFunc_Spawn, iMuzzleFlash)
    set_member(iEntity, m_Weapon_iFamasShotsFired, iMuzzleFlash)
}

@Dummy1(time) return

@Dummy2(time) return

CreateCvars()
{
    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_access",
        .string = "b",
        .description = CVAR_DESC("REAPI_MOLOTOV_ACCESS")),
        eCvarData[ACCESS],
        charsmax(eCvarData[ACCESS])
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_access_spawn",
        .string = "a",
        .description = CVAR_DESC("REAPI_MOLOTOV_ACCESS_SPAWN")),
        eCvarData[ACCESS_SPAWN],
        charsmax(eCvarData[ACCESS_SPAWN])
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_use_pickup",
        .string = "1",
        .description = CVAR_DESC("REAPI_MOLOTOV_USE_PICKUP"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[USE_PICKUP]
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_access_pickup",
        .string = "t",
        .description = CVAR_DESC("REAPI_MOLOTOV_ACCESS_PICKUP")),
        eCvarData[ACCESS_PICKUP],
        charsmax(eCvarData[ACCESS_PICKUP])
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_dmg_tm",
        .string = "0",
        .description = CVAR_DESC("REAPI_MOLOTOV_DMG_TM"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[DMG_TM]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_dmg",
        .string = "3.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_DMG")),
        eCvarData[DMG]
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_random_dmg",
        .string = "5.0-10.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_RANDOM_DAMAGE")),
        eCvarData[RANDOM_DAMAGE],
        charsmax(eCvarData[RANDOM_DAMAGE])
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_damage_flags",
        .string = "1",
        .description = CVAR_DESC("REAPI_MOLOTOV_DAMAGE_FLAGS"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[DAMAGE_FLAGS]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_firetime",
        .string = "10.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_FIRETIME")),
        eCvarData[FIRETIME]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_radius",
        .string = "90.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_RADIUS")),
        eCvarData[RADIUS]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_dmg_tick",
        .string = "0.7",
        .description = CVAR_DESC("REAPI_MOLOTOV_DMG_TICK")),
        eCvarData[DMG_TICK]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_anim_tick",
        .string = "1.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_ANIM_TICK")),
        eCvarData[ANIM_TICK]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_long_delay_use",
        .string = "1",
        .description = CVAR_DESC("REAPI_MOLOTOV_LG_USE"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[LONG_DELAY_USE]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_long_delay_time",
        .string = "5.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_LG_TIME")),
        eCvarData[LONG_DELAY_TIME]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_long_delay_kill",
        .string = "1",
        .description = CVAR_DESC("REAPI_MOLOTOV_LG_KILL"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[LONG_DELAY_KILL]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_time_of_detonate",
        .string = "0.8",
        .description = CVAR_DESC("REAPI_MOLOTOV_TIME_OF_DETONATE")),
        eCvarData[TIME_OF_DETONATE]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_impact_sound_time",
        .string = "0.6",
        .description = CVAR_DESC("REAPI_MOLOTOV_IMPACT_SOUND_TIME")),
        eCvarData[IMPACT_SOUND_TIME]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_get_in_spawn",
        .string = "0",
        .description = CVAR_DESC("REAPI_MOLOTOV_GET_IN_SPAWN"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[GET_IN_SPAWN]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_extinguishing",
        .string = "1",
        .description = CVAR_DESC("REAPI_MOLOTOV_EXTINGUISHING"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[EXTINGUISHING]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_extinguishing_time",
        .string = "1.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_EXTINGUISHING_TIME")),
        eCvarData[EXTINGUISHING_TIME]
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_radius_multiplier",
        .string = "3.0",
        .description = CVAR_DESC("REAPI_MOLOTOV_RADIUS_MULTIPLIER")),
        eCvarData[RADIUS_MULTIPLIER]
    )

    #if defined _gamecms5_included
    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_game_cms_services",
        .string = "_molotov_name1",
        .description = CVAR_DESC("REAPI_MOLOTOV_GAME_CMS_SERVICES")),
        GAME_CMS_SERVICES,
        charsmax(GAME_CMS_SERVICES)
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_infinite_flags_gamecms",
        .string = "_molotov_name2",
        .description = CVAR_DESC("REAPI_MOLOTOV_INFINITE_FLAGS_GAME_CMS")),
        INFINITE_USAGE_FLAGS_GAMECMS,
        charsmax(INFINITE_USAGE_FLAGS_GAMECMS)
    )
    #endif

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_restriction_on_use",
        .string = "0",
        .description = CVAR_DESC("REAPI_MOLOTOV_RESTRICTION_ON_USE"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[RESTRICTION_ON_USE]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_time_limit_on_usage",
        .string = "15",
        .description = CVAR_DESC("REAPI_MOLOTOV_TIME_LIMIT_ON_USAGE")),
        eCvarData[TIME_LIMIT_ON_USAGE]
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_infinite_flags",
        .string = "ab",
        .description = CVAR_DESC("REAPI_MOLOTOV_INFINITE_FLAGS")),
        eCvarData[INFINITE_USAGE_FLAGS],
        charsmax(eCvarData[INFINITE_USAGE_FLAGS])
    )

    bind_pcvar_float(create_cvar(
        .name = "reapi_molotov_effect_scale",
        .string = "0.05",
        .description = CVAR_DESC("REAPI_MOLOTOV_EFFECT_SCALE")),
        eCvarData[FIRE_EFF]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_buy_mode",
        .string = "1",
        .description = CVAR_DESC("BUY_MOLOTOV"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[BUY_MOLOTOV]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_cost",
        .string = "10000",
        .description = CVAR_DESC("MOLOTOV_COST")),
        eCvarData[MOLOTOV_COST]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_rnd_limit_buy",
        .string = "4",
        .description = CVAR_DESC("ROUND_LIMIT_BUY")),
        eCvarData[ROUND_LIMIT_BUY]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_rnd_limit_issuing",
        .string = "3",
        .description = CVAR_DESC("ROUND_LIMIT_ISSUING")),
        eCvarData[ROUND_LIMIT_ISSUING]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_play_err_sound",
        .string = "1",
        .description = CVAR_DESC("PLAY_ERROR_SOUND"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[PLAY_ERROR_SOUND]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_err_snd_mode",
        .string = "6",
        .description = CVAR_DESC("PLAY_ERROR_SOUND_MODE")),
        eCvarData[PLAY_ERROR_SOUND_MODE]
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_err_snd_path_name",
        .string = "buttons/blip2.wav",
        .description = CVAR_DESC("ERROR_SOUND_PATH_AND_NAME")),
        eCvarData[ERROR_SOUND_PATH_AND_NAME],
        charsmax(eCvarData[ERROR_SOUND_PATH_AND_NAME])
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_checking_buy_zone",
        .string = "1",
        .description = CVAR_DESC("CHECKING_BUY_ZONE"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[CHECKING_BUY_ZONE]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_time_to_buy",
        .string = "10",
        .description = CVAR_DESC("TIME_TO_BUY")),
        eCvarData[TIME_TO_BUY]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_give_limit",
        .string = "3",
        .description = CVAR_DESC("GIVE_LIMIT")),
        eCvarData[GIVE_LIMIT]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_give_buy_zone",
        .string = "1",
        .description = CVAR_DESC("GIVE_BUY_ZONE"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[GIVE_BUY_ZONE]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_give_time_to_buy",
        .string = "15",
        .description = CVAR_DESC("GIVE_TIME_TO_BUY")),
        eCvarData[GIVE_TIME_TO_BUY]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_eff_team_designation",
        .string = "1",
        .description = CVAR_DESC("EFFECT_TEAM_DESIGNATION"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[EFFECT_TEAM_DESIGNATION]
    )

    bind_pcvar_num(create_cvar(
        .name = "reapi_molotov_eff_circle_color_modes",
        .string = "1",
        .description = CVAR_DESC("EFFECT_CIRCLE_COLOR_MODES"),
        .has_min = true,
        .min_val = 0.0,
        .has_max = true,
        .max_val = 1.0),
        eCvarData[EFFECT_CIRCLE_COLOR_MODES]
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_eff_color",
        .string = "255 43 43 0 0 255",
        .description = CVAR_DESC("EFFECT_COLOR_CT_AND_T")),
        eCvarData[EFFECT_COLOR_CT_AND_T],
        charsmax(eCvarData[EFFECT_COLOR_CT_AND_T])
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_eff_color_rnd",
        .string = "50 255 100 200 30 165 30 170 150 255 60 180",
        .description = CVAR_DESC("EFFECT_COLOR_CT_AND_T_RND")),
        eCvarData[EFFECT_COLOR_CT_AND_T_RND],
        charsmax(eCvarData[EFFECT_COLOR_CT_AND_T_RND])
    )

    bind_pcvar_string(create_cvar(
        .name = "reapi_molotov_other_eff_settings",
        .string = "2 11 45 230",
        .description = CVAR_DESC("OTHER_EFFECT_SETTINGS")),
        eCvarData[OTHER_EFFECT_SETTINGS],
        charsmax(eCvarData[OTHER_EFFECT_SETTINGS])
    )
}

//thx: https://amx-x.ru/viewtopic.php?p=41740#p41740

@CircleEffect(saving_array[], id)
{
    new Float:vecEndPos[3]

    vecEndPos[0] = float(saving_array[0])
    vecEndPos[1] = float(saving_array[1])
    vecEndPos[2] = float(saving_array[2])

    engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, vecEndPos, 0)

    write_byte(TE_BEAMCYLINDER) // TE id

    engfunc(EngFunc_WriteCoord, vecEndPos[0]) // x
    engfunc(EngFunc_WriteCoord, vecEndPos[1]) // y
    engfunc(EngFunc_WriteCoord, vecEndPos[2]) // z

    engfunc(EngFunc_WriteCoord, vecEndPos[0]) // x axis
    engfunc(EngFunc_WriteCoord, vecEndPos[1]) // y axis
    engfunc(EngFunc_WriteCoord, vecEndPos[2] + eCvarData[RADIUS]) // z axis

    write_short(SPRITE_CIRCLE_ID) // sprite index

    write_byte(0) // startframe
    write_byte(0) // framerate
    write_byte(GlobalSettingsEff[EFF_LIFE]) // life
    write_byte(GlobalSettingsEff[EFF_WIDTH]) // width
    write_byte(0) // noise

    new bool:CheckTeam = (get_user_team(id) == 1 ? true : false)

    new Color[6]

    Color[0] = eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? random_num(GlobalColorsRndEff[EFF_CT_R_MIN], GlobalColorsRndEff[EFF_CT_R_MAX]) : GlobalColorsEff[EFF_CT_R]
    Color[1] = eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? random_num(GlobalColorsRndEff[EFF_CT_G_MIN], GlobalColorsRndEff[EFF_CT_G_MAX]) : GlobalColorsEff[EFF_CT_G]
    Color[2] = eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? random_num(GlobalColorsRndEff[EFF_CT_B_MIN], GlobalColorsRndEff[EFF_CT_B_MAX]) : GlobalColorsEff[EFF_CT_B]
    Color[3] = eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? random_num(GlobalColorsRndEff[EFF_T_R_MIN], GlobalColorsRndEff[EFF_T_R_MAX]) : GlobalColorsEff[EFF_T_R]
    Color[4] = eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? random_num(GlobalColorsRndEff[EFF_T_G_MIN], GlobalColorsRndEff[EFF_T_G_MAX]) : GlobalColorsEff[EFF_T_G]
    Color[5] = eCvarData[EFFECT_CIRCLE_COLOR_MODES] ? random_num(GlobalColorsRndEff[EFF_T_B_MIN], GlobalColorsRndEff[EFF_T_B_MAX]) : GlobalColorsEff[EFF_T_B]

    write_byte(CheckTeam ? Color[0] : Color[3]) // r
    write_byte(CheckTeam ? Color[1] : Color[4]) // g
    write_byte(CheckTeam ? Color[2] : Color[5]) // b

    write_byte(GlobalSettingsEff[EFF_BRIGHTNESS]) // brightness
    write_byte(0) // speed

    message_end()
}

stock rg_get_player_item(const id, const classname[], const InventorySlotType:slot = NONE_SLOT)
{
    new item = get_member(id, m_rgpPlayerItems, slot)

    while(!is_nullent(item))
    {
        if(FClassnameIs(item, classname)) return item
        item = get_member(item, m_pNext)
    }

    return 0
}

stock UTIL_WeapoList(
    const type,
    const player,
    const name[],
    const ammo1,
    const maxAmmo1,
    const ammo2,
    const maxammo2,
    const InventorySlotType:slot,
    const position,
    const WeaponIdType:id,
    const flags
) {
    message_begin(type, MsgIdWeaponList, .player = player)
    write_string(name)
    write_byte(ammo1)
    write_byte(maxAmmo1)
    write_byte(ammo2)
    write_byte(maxammo2)
    write_byte(_:slot - 1)
    write_byte(position)
    write_byte(_:id)
    write_byte(flags)
    message_end()
}

stock UTIL_StatusIcon(const player, const type, const sprite[], const color[3])
{
    message_begin(MSG_ONE, MsgIdStatusIcon, .player = player)
    write_byte(type) // 0 - hide 1 - show 2 - flash
    write_string(sprite)
    write_byte(color[0])
    write_byte(color[1])
    write_byte(color[2])
    message_end()
}

//thx: https://dev-cs.ru/threads/222/post-2173

stock SignalState:rg_get_user_mapzones(const player)
{
    new iSignals[UnifiedSignals]
    get_member(player, m_signals, iSignals)

    return SignalState:iSignals[US_State]
}

stock bool:rg_user_in_buyzone(const player)
{
    return bool:(rg_get_user_mapzones(player) & SIGNAL_BUY)
}
Требования
Использование последних версий Re-* продуктов для:

1. Компилирования плагина. (reapi)
2. Сервера где установлен плагин. (regamedll, reapi)

Amx Mod X 1.9.0, Amx Mod X 1.10.0 dev
Требование ReAPI
Да
Поддержка русского языка
Да
Совместимость
  1. REHLDS
Сверху Снизу