Healthnade & ReApi Molotov - BUG

Сообщения
8
Реакции
1
Ошибка
Ошибок нет!
ОС
Linux
Amx Mod X
AmxModX 1.9.0
Билд
ReHLDS version: 3.13.0.788-dev-mpatch
ReGamedll
ReGameDLL version: 5.21.0.556-dev
Версия Metamod
Metamod v1.21p37  2013/05/30 (5:13)
Список метамодулей
[ 1] AMX Mod X        RUN   -    amxmodx_mm_i386.  v1.9.0.5  ini   Start ANY  
[ 2] SafeNameAndChat RUN - SafeNameAndChat. v1.1 ini ANY ANY
[ 3] Reunion RUN - reunion_mm_i386. v0.1.92d ini Start Never
[ 4] ReSemiclip RUN - resemiclip_mm_i3 v2.3.9 ini Chlvl ANY
[ 5] VoiceTranscoder RUN - VoiceTranscoder. v2017RC5 ini ANY ANY
[ 6] MySQL RUN - mysql_amxx_i386. v1.9.0.5 pl1 ANY ANY
[ 7] SQLite RUN - sqlite_amxx_i386 v1.9.0.5 pl1 ANY ANY
[ 8] Fun RUN - fun_amxx_i386.so v1.9.0.5 pl1 ANY ANY
[ 9] Engine RUN - engine_amxx_i386 v1.9.0.5 pl1 ANY ANY
[10] FakeMeta RUN - fakemeta_amxx_i3 v1.9.0.5 pl1 ANY ANY
[11] GeoIP RUN - geoip_amxx_i386. v1.9.0.5 pl1 ANY ANY
[12] CStrike RUN - cstrike_amxx_i38 v1.9.0.5 pl1 ANY ANY
[13] CSX RUN - csx_amxx_i386.so v1.9.0.5 pl1 ANY ANY
[14] Ham Sandwich RUN - hamsandwich_amxx v1.9.0.5 pl1 ANY ANY
[15] ReAPI RUN - reapi_amxx_i386. v5.22.0. pl1 ANY Never
Список плагинов
[  1] GameCMS_API             5.6.1       zhorzh78          gamecms_api_5.6  running  
[ 2] FreshBans 1.4.8b kanagava fresh_bans.amxx running
[ 3] Admin Commands 1.9.0.5294 AMXX Dev Team admincmd.amxx running
[ 4] Players Menu 1.9.0.5294 AMXX Dev Team plmenu.amxx running
[ 5] Maps Menu 1.9.0.5294 AMXX Dev Team mapsmenu.amxx running
[ 6] Admin Chat 1.9.0.5294 AMXX Dev Team adminchat.amxx running
[ 7] Anti Flood 1.9.0.5294 AMXX Dev Team antiflood.amxx running
[ 8] Admin Votes 1.9.0.5294 AMXX Dev Team adminvote.amxx running
[ 9] ReMapChooser 0.0.2 PurposeLess remapchooser.am running
[ 10] Stats Configuration 20.06.06 SKAJIbnEJIb & AM statscfg_rbs.am running
[ 11] [190] StatsX Unlimited 22.12.08 SKAJIbnEJIb statsx_unlimite running
[ 12] [190] StatsX RBS 21.03.23 SKAJIbnEJIb & AM statsx_rbs.amxx running
[ 13] Restrict Weapons 1.9.0.5294 AMXX Dev Team restmenu.amxx running
[ 14] unknown unknown unknown advertisement.a running
[ 15] unknown unknown unknown autorestart.amx running
[ 16] Re Menus Front-End 1.9.0 | 0. hurricane / AMXX re_menufront.am running
[ 17] resetscore 1.0 Heart Of Love resetscore.amxx running
[ 18] [190] Parachute RBS 22.11.15 SKAJIbnEJIb & KR parachute_rbs.a running
[ 19] [190] Damager RBS 20.06.06 SKAJIbnEJIb damager_rbs.amx running
[ 20] [190] No Team Flash 20.06.06 SKAJIbnEJIb NoTeamFlash.amx running
[ 21] [190] Snipers RBS 20.06.06 SKAJIbnEJIb snipers_rbs.amx running
[ 22] [190] Ultimate Informe 21.03.23 SKAJIbnEJIb ultimate_inform running
[ 23] [190] Army Ranks Ultim 20.06.06 SKAJIbnEJIb army_ranks_ulti running
[ 24] [190] AR Pogony 20.06.06 SKAJIbnEJIb ar_pogony.amxx running
[ 25] [190] BackWeapons RBS 20.06.06 SKAJIbnEJIb & ho backweapons_rbs running
[ 26] [190] VoteBan RBS 20.06.06 SKAJIbnEJIb voteban_rbs.amx running
[ 27] [ReAPI] Healthnade 0.0.12f DEV-CS.RU Commun reapi_healthnad running
[ 28] Style C4 Timer 3.1 OciXCrom crx_c4timer.amx running
[ 29] [ReAPI] Molotov Api Te 0.0.2 wellasgood reapi_molotov_a running
[ 30] [ReAPI] Molotov 2.5.1 wellasgood reapi_molotov.a running
[ 31] ChatAdditions: Core v1.9.1 Sergey Shorokhov ChatAdditions_C debug
[ 32] ChatAdditions: GameCMS v1.9.1 Sergey Shorokhov CA_Storage_Game debug
[ 33] CA: Mute v1.9.1 Sergey Shorokhov CA_Mute.amxx debug
[ 34] CA Addon: Request UnGA v1.9.1 steelzzz CA_Addon_Reques debug
[ 35] CA: Gag v1.9.1 Sergey Shorokhov CA_Gag.amxx debug
Автор плагина
wellasgood
Версия плагина
[Reapi] Molotov 2.5.1
Исходный код
#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)
}
Добрый день!

Установил на сервер "[Reapi] Molotov 2.5.1" и "[Fork] Healthnade 0.0.12f". Когда включены эти 2 плагина, то молтов не работает. Выдается, но взять его не возможно... а хил гранату вообще не выдает! Коктель молотова, можно взять только - через админ команду! Подскажите пожалуйста в чем дело... никак не могу разобраться в чем проблема. Почему они между собой не дружат - хотя слоты разные под них!
 

Вложения

Сообщения
282
Реакции
34
Помог
3 раз(а)
Can you share config file of health nade and molotov coctail?
It might be issue in weapon slots cvar.
You can try with:
HealthNade_SlotId "4"
 
Сообщения
3,593
Реакции
1,576
Помог
141 раз(а)
Они сделаны на основе одного и того же неиспользуемого ID оружия GLOCK (не путать с GLOCK18). Нужно заменить в одном из исходников WEAPON_GLOCK на другое оружие. Но оно будет недоступно. Нужно использовать оружие с которым никто не будет играть. Например, TMP какой-нибудь или скорострелки, если они запрещены.
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
Nordic Warrior, а разве достаточно сменить айтем айди? А аммо айди и позицию в слоте разве не обязательно менять?
 
Сообщения
3,593
Реакции
1,576
Помог
141 раз(а)
ImmortalAmxx, не помню, давно сам это делал. Теперь ты написал и я сомневаюсь, возможно надо
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
Если не ошибаюсь, там нужно указывать позицию и другой аммо айди.
Автор поста - попробуй эту версию
Код:
#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_TMP
const WeaponIdType:WEAPON_FAKE_ID = WeaponIdType:80
const AMMO_ID = 18
const WEAPLIST_POS = 5

#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, WEAPLIST_POS, 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, WEAPLIST_POS)
    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)
}
 
Последнее редактирование модератором:
Сообщения
8
Реакции
1
Молотов выдается только админам. Простым игрокам нет... Хотя в CVARS, данная функция отключена! Запрет на оружие стоит "TMP"
 
Сообщения
8
Реакции
1
Добрый день! Проблемы с выдачей решил... Подскажите пожалуйста, как убрать вывод сообщений(screen).
 

Вложения

Сообщения
365
Реакции
9
Помог
5 раз(а)
Обратите внимание, если вы хотите заключить сделку с этим пользователем, он заблокирован
Сообщения
893
Реакции
149
Помог
25 раз(а)
sanjka095, покажи код гранаты хилки. После смены квар молотова ты карту меняешь или рестарт сервера делаешь?
 
Сообщения
8
Реакции
1
Код:
/*
    Форк лечебной гранаты на основе Healthnade 0.0.2 от F@nt0M: https://dev-cs.ru/resources/992/

    GitHub: https://github.com/Giferns/HealthNade

    0.0.3f:
        * Добавлена возможность пить зелье на ПКМ (спасибо AnonymousAmx, MayroN, Psycrow)
            * Опция HEAL_AMOUNT переименована в HEAL_AMOUNT_THROW
            * Добавлена опция HEAL_AMOUNT_DRINK
            * Добавлены опции USAGE_MSG и FULL_HP_MSG
            * Заменена модель в руках (v_) на модель с анимацией выпивания
            * Добавлен звук выпивания (обрататие внимание, модель содержит другие пути к звукам!)

    0.0.4f:
        * Добавлена опция MIN_ROUND (минимальный раунд для автовыдачи по флагу)
    0.0.5f:
        * Добавлен натив HealthNade_GiveNade()
    0.0.6f:
        * Перенос параметров хилки в переменные сущности: https://github.com/Giferns/HealthNade/pull/1
    0.0.7f:
        * Добавлены квары и словарь
    0.0.8f:
        * Фикс учёта mp_nadedrops (теперь учитывает значение на лету)
        * Добавлен недостающий учёт квара HealthNade_Give
        * Значение квара HealthNade_Give по-умолчанию теперь 1 (было 0)
        * Исправлена логика создания кастомного веапонбокса
    0.0.9f:
        * Добавлен квар HealthNade_SlotId
    0.0.10f:
        * Добавлен квар HealthNade_EquipDelay
    0.0.11f
        * Добавлен квар HealthNade_ReplaceSmokegren
    0.0.12f
        * Добавлен квар HealthNade_Drink_AccessFlags
*/

new const PLUGIN_VERSION[] = "0.0.12f";

#pragma semicolon 1

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#include <xs>
#include <healthnade>

enum E_NadeDropType {
    NadeDrop_Off = 0,
    NadeDrop_On = 1,
    NadeDrop_ByCvar = 2,
}

enum E_Cvars {
    Float:Cvar_ExplodeRadius,
    Float:Cvar_ThrowHealingAmount,
    Float:Cvar_DrinkHealingAmount,
    bool:Cvar_Give,
    Cvar_Give_AccessFlags[16],
    Cvar_Drink_AccessFlags[16],
    Cvar_Give_MinRound,
    Float:Cvar_EquipDelay,
    bool:Cvar_ReplaceSmokegren,
    bool:Cvar_Msg_FullHp,
    bool:Cvar_Msg_UsageHint,
    E_NadeDropType:Cvar_NadeDrop,
    InventorySlotType:Cvar_SlotId,
}
new gCvars[E_Cvars];
#define Cvar(%1) gCvars[Cvar_%1]

new const DICTIONARY_FILENAME[] = "HealthNade.ini";

#define LangS(%1) fmt("%l", %1)

const WeaponIdType:WEAPON_ID = WEAPON_SMOKEGRENADE;
const WeaponIdType:WEAPON_NEW_ID = WEAPON_GLOCK;
const WeaponIdType:WEAPON_FAKE_ID = WeaponIdType:75;
new const WEAPON_NAME[] = "weapon_smokegrenade";
new const AMMO_NAME[] = "HealthNade";
new const WEAPON_NEW_NAME[] = "reapi_healthnade/weapon_healthnade";
new const ITEM_CLASSNAME[] = "weapon_healthnade";
new const GRENADE_CLASSNAME[] = "healthnade";
const AMMO_ID = 16;
const InventorySlotType:ITEM_SLOT = GRENADE_SLOT;

new const VIEWMODEL[] = "models/reapi_healthnade/v_drink9.mdl";
new const WEAPONMODEL[] = "models/reapi_healthnade/p_healthnade.mdl";
new const WORLDMODEL[] = "models/reapi_healthnade/w_healthnade.mdl";
new const SOUND_PULLPIN[] = "weapons/holywater_pinpul.wav";
new const SOUND_DEPLOY[] = "weapons/holywater_deploy.wav";
new const SOUND_DRINK[] = "weapons/holywater_drink.wav";
new const SOUND_EXPLODE[] = "weapons/reapi_healthnade/heal.wav";
// TODO: Вынести остальные пути в константы

#define rg_get_current_round() (get_member_game(m_iTotalRoundsPlayed) + 1)

// copy_entvar(const iEntFrom, const iEntTo, const EntVar:iVar)
#define copy_entvar(%1,%2,%3) set_entvar(%2, %3, get_entvar(%1, %3))

new SpriteCylinder, SpriteExplode, SpriteShape;
new MsgIdWeaponList, MsgIdAmmoPickup, MsgIdStatusIcon, MsgIdScreenFade;
#if WEAPON_NEW_ID != WEAPON_GLOCK
new FwdRegUserMsg, MsgHookWeaponList;
#endif
new g_iCvarNadeDrops;

public plugin_precache() {
    register_plugin("[ReAPI] Healthnade", PLUGIN_VERSION, "DEV-CS.RU Community");
    register_dictionary(DICTIONARY_FILENAME);

    InitCvars();

    precache_generic("sprites/reapi_healthnade/weapon_healthnade.txt");
    precache_generic("sprites/reapi_healthnade/640hud128.spr");

    precache_model(VIEWMODEL);
    precache_model(WEAPONMODEL);
    precache_model(WORLDMODEL);

    precache_sound(SOUND_PULLPIN);
    precache_sound(SOUND_DEPLOY);
    precache_sound(SOUND_DRINK);

    SpriteExplode = precache_model("sprites/reapi_healthnade/heal_explode.spr");
    SpriteShape = precache_model("sprites/reapi_healthnade/heal_shape.spr");
    SpriteCylinder = precache_model("sprites/shockwave.spr");

    precache_sound("weapons/reapi_healthnade/heal.wav");

#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
}

public plugin_init() {
    register_clcmd(WEAPON_NEW_NAME, "CmdSelect");

    RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "CBasePlayer_OnSpawnEquip_Post", true);
    RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed_Pre", false);

    RegisterHookChain(RG_CSGameRules_CleanUpMap, "CSGameRules_CleanUpMap_Post", true);
    RegisterHookChain(RG_CBasePlayer_GiveAmmo, "CBasePlayer_GiveAmmo_Pre", false);
    RegisterHookChain(RG_CBasePlayerWeapon_DefaultDeploy, "CBasePlayerWeapon_DefaultDeploy_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_SecondaryAttack, WEAPON_NAME, "CBasePlayerWeapon_SecondaryAttack_Post", true);
    RegisterHam(Ham_Item_PostFrame, WEAPON_NAME, "CBasePlayerWeapon_ItemPostFrame_Pre");

    RegisterHookChain(RG_CBasePlayer_ThrowGrenade, "CBasePlayer_ThrowGrenade_Pre", false);

    RegisterHookChain(RG_CBasePlayer_AddPlayerItem, "CBasePlayer_AddPlayerItem_Pre");
    RegisterHookChain(RG_CBasePlayer_HasRestrictItem, "CBasePlayer_HasRestrictItem_Pre");

    MsgIdAmmoPickup = get_user_msgid("AmmoPickup");
    MsgIdStatusIcon = get_user_msgid("StatusIcon");
    MsgIdScreenFade = get_user_msgid("ScreenFade");

#if WEAPON_NEW_ID == WEAPON_GLOCK
    MsgIdWeaponList = get_user_msgid("WeaponList");
    UTIL_WeapoList(
        MSG_INIT, 0,
        WEAPON_NEW_NAME,
        AMMO_ID, 1,
        -1, -1, Cvar(SlotId), 4, WEAPON_NEW_ID,
        ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE
    );
#else
    if (FwdRegUserMsg) {
        unregister_forward(FM_RegUserMsg, FwdRegUserMsg, true);
    }
    unregister_message(MsgIdWeaponList, MsgHookWeaponList);
#endif
}

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

public 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, _:Cvar(SlotId) - 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

public CBasePlayer_OnSpawnEquip_Post(const id) {
    remove_task(id);

    if (!Cvar(Give) || !UserHasFlagsS(id, Cvar(Give_AccessFlags))) {
        return;
    }

    if(rg_get_current_round() < Cvar(Give_MinRound)) {
        return;
    }

    if(!Cvar(EquipDelay)) {
        giveNade(id);
        return;
    }

    set_task(Cvar(EquipDelay), "task_DelayedEquip", id);
}

public task_DelayedEquip(const id) {
    if(is_user_alive(id)) {
        giveNade(id);
    }
}

public CBasePlayer_Killed_Pre(const id) {
    if (Cvar(NadeDrop) == NadeDrop_Off) {
        return;
    }

    if (Cvar(NadeDrop) == NadeDrop_ByCvar) {
        switch (g_iCvarNadeDrops) {
            case 0:
                return;
            case 1: {
                new iItem = get_member(id, m_rgpPlayerItems, ITEM_SLOT);

                if (is_nullent(iItem) || !FClassnameIs(iItem, ITEM_CLASSNAME)) {
                    return;
                }
            }
        }
    }

    if (!get_member(id, m_rgAmmo, AMMO_ID)) {
        return;
    }

    new eEnt, Float:fOrigin[3];

    get_entvar(id, var_origin, fOrigin);

    new Float:fVelocity[3];
    get_entvar(id, var_velocity, fVelocity);
    xs_vec_mul_scalar(fVelocity, 0.75, fVelocity);

    eEnt = rg_create_entity("info_target");

    if(is_nullent(eEnt)) {
        return;
    }

    set_entvar(eEnt, var_classname, "healthnade_drop");

    engfunc(EngFunc_SetOrigin, eEnt, fOrigin);
    set_entvar(eEnt, var_movetype, MOVETYPE_TOSS);
    set_entvar(eEnt, var_solid, SOLID_TRIGGER);
    engfunc(EngFunc_SetModel, eEnt, WORLDMODEL);
    engfunc(EngFunc_SetSize, eEnt, Float:{-6.0, -6.0, -1.0}, Float:{6.0, 6.0, 1.0});

    set_entvar(eEnt, var_velocity, fVelocity);
    SetThink(eEnt, "think_healthnade_drop");
    set_entvar(eEnt, var_nextthink, get_gametime() + get_cvar_float("mp_item_staytime"));

    SetTouch(eEnt, "touch_healthnade_drop");
}

public think_healthnade_drop(const eEnt) {
    if(is_entity(eEnt)) {
        set_entvar(eEnt, var_flags, FL_KILLME);
    }
}

public touch_healthnade_drop(const eEnt, const id) {
    if (
        is_nullent(eEnt)
        || !is_user_connected(id)
        || get_member(id, m_rgAmmo, AMMO_ID)
    ) {
        return;
    }

    set_entvar(eEnt, var_nextthink, -1.0);
    set_entvar(eEnt, var_flags, FL_KILLME);

    giveNade(id);
}

public CmdSelect(const id) {
    if (!is_user_alive(id)) {
        return PLUGIN_HANDLED;
    }

    new item = rg_get_player_item(id, ITEM_CLASSNAME, ITEM_SLOT);
    if (item != 0 && get_member(id, m_pActiveItem) != item) {
        rg_switch_weapon(id, item);
    }
    return PLUGIN_HANDLED;
}

public 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, "healthnade_drop", false);
    while (ent > 0) {
        destroyNade(ent);
        ent = rg_find_ent_by_class(ent, "healthnade_drop", false);
    }
}

public 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;
}


public CBasePlayerWeapon_DefaultDeploy_Pre(const item, const szViewModel[], const szWeaponModel[], const iAnim, const szAnimExt[], const skiplocal) {
    new UserId = get_member(item, m_pPlayer);

    if (FClassnameIs(item, ITEM_CLASSNAME)) {
        SetHookChainArg(2, ATYPE_STRING, VIEWMODEL);
        SetHookChainArg(3, ATYPE_STRING, WEAPONMODEL);

        if (Cvar(Msg_UsageHint)) {
            client_print(UserId, print_center, "%L", UserId, "HEALTHNADE_USAGE_HINT");
        }
    }

    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(UserId, 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;
}

public 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, ITEM_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);
    }
}

public Item_Holster_Post(const item) {
    new other = get_member(get_member(item, m_pPlayer), m_rgpPlayerItems, ITEM_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);
    }
}

enum {
    HG_ANIMATION_IDLE = 0,
    HG_ANIMATION_PULLPIN,
    HG_ANIMATION_THROW,
    HG_ANIMATION_DEPLOY,
    HG_ANIMATION_DRINK
};

public CBasePlayerWeapon_SecondaryAttack_Post(weapon) {
    if(!is_entity(weapon) || !FClassnameIs(weapon, ITEM_CLASSNAME)) {
        return;
    }

    set_member(weapon, m_Weapon_flNextSecondaryAttack, 0.3);

    if(get_member(weapon, m_flStartThrow) > 0.0) {
        return;
    }

    new pPlayer = get_member(weapon, m_pPlayer);

    new iBpAmmo = get_member(pPlayer, m_rgAmmo, AMMO_ID);

    if(!iBpAmmo) {
        return;
    }

    if(!UserHasFlagsS(pPlayer, Cvar(Drink_AccessFlags))) {
        client_print(pPlayer, print_center, "%L", pPlayer, "HEALTHNADE_NO_ACCESS");
        return;
    }

    if(Float:get_entvar(pPlayer, var_health) >= Float:get_entvar(pPlayer, var_max_health)) {
        if (Cvar(Msg_FullHp)) {
            client_print(pPlayer, print_center, "%L", pPlayer, "HEALTHNADE_FULL_HP");
        }

        return;
    }

    const Float:fAnimTime = 3.15; // 63 frames / 20 fps
    set_member(weapon, m_Weapon_flTimeWeaponIdle, fAnimTime);
    set_member(weapon, m_Weapon_flNextPrimaryAttack, fAnimTime);
    set_member(weapon, m_Weapon_flNextSecondaryAttack, fAnimTime);
    SendWeaponAnimation(pPlayer, HG_ANIMATION_DRINK);
}

// PostFrame() а не WeaponIdle() т.к. при прожатых IN_ATTACK|IN_ATTACK2|IN_RELOAD WeaponIdle() не вызывается
// т.е. зажатие любой из этих кнопок приведёт к неработоспособности логики
public CBasePlayerWeapon_ItemPostFrame_Pre(weapon) {
    if(/*!is_entity(weapon) || */!FClassnameIs(weapon, ITEM_CLASSNAME)) {
        return;
    }

    if(get_member(weapon, m_Weapon_flTimeWeaponIdle) > 0.0) {
        return;
    }

    new pPlayer = get_member(weapon, m_pPlayer);

    if(get_entvar(pPlayer, var_weaponanim) != HG_ANIMATION_DRINK) {
        return;
    }

    // Нам надо обеспечить вызов WeaponIdle()
    // https://github.com/s1lentq/ReGameDLL_CS/blob/67cc153f5d0abab1e42b32a83ef4a470c8781a5c/regamedll/dlls/weapons.cpp#L1007
    // https://github.com/s1lentq/ReGameDLL_CS/blob/67cc153f5d0abab1e42b32a83ef4a470c8781a5c/regamedll/dlls/weapons.cpp#L1019
    // https://github.com/s1lentq/ReGameDLL_CS/blob/67cc153f5d0abab1e42b32a83ef4a470c8781a5c/regamedll/dlls/weapons.cpp#L1092
    set_entvar(pPlayer, var_button, get_entvar(pPlayer, var_button) & ~(IN_ATTACK|IN_ATTACK2|IN_RELOAD));

    new iBpAmmo = get_member(pPlayer, m_rgAmmo, AMMO_ID);

    if(!iBpAmmo) {
        return;
    }

    set_member(pPlayer, m_rgAmmo, iBpAmmo - 1, AMMO_ID);

    // RetireWeapon() средствами regamedll если бпаммо нет, либо отправка анимации деплоя
    // https://github.com/s1lentq/ReGameDLL_CS/blob/b979b5e84f36dc0eb870f97da670b700756217f1/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp#L225
    set_member(weapon, m_flReleaseThrow, 0.1);

    ExecuteHamB(Ham_TakeHealth, pPlayer, get_entvar(weapon, var_HealthNade_DrinkHealingAmount), DMG_GENERIC);
    UTIL_ScreenFade(pPlayer);
}

stock SendWeaponAnimation(const id, const iAnimation) {
    set_entvar(id, var_weaponanim, iAnimation);

    message_begin(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, .player = id);
    write_byte(iAnimation);
    write_byte(0);
    message_end();
}

public CBasePlayer_ThrowGrenade_Pre(const id, const item, const Float:vecSrc[3], const Float:vecThrow[3], const Float:time, const const usEvent) {
    if (!FClassnameIs(item, ITEM_CLASSNAME)) {
        return HC_CONTINUE;
    }

    new grenade = throwNade(id, item, vecSrc, vecThrow, time);
    SetHookChainReturn(ATYPE_INTEGER, grenade);
    return HC_SUPERCEDE;
}

public CBasePlayer_AddPlayerItem_Pre(const id, const item) {
    if(!Cvar(ReplaceSmokegren) || is_nullent(item) || get_member(item, m_iId) != WEAPON_SMOKEGRENADE || !is_user_alive(id)) {
        return HC_CONTINUE;
    }

    set_entvar(item, var_flags, FL_KILLME);

    giveNade(id);

    SetHookChainReturn(ATYPE_INTEGER, 0);
    return HC_SUPERCEDE;
}

public CBasePlayer_HasRestrictItem_Pre(id, ItemID:item, ItemRestType:rest_type) {
    if(!Cvar(ReplaceSmokegren)) {
        return HC_CONTINUE;
    }

    if(item ==ITEM_SMOKEGRENADE && rg_get_player_item(id, ITEM_CLASSNAME, ITEM_SLOT)) {
        if(rest_type == ITEM_TYPE_BUYING) {
            client_print(id, print_center, "#Cstrike_TitlesTXT_Cannot_Carry_Anymore");
        }

        SetHookChainReturn(ATYPE_BOOL, true);
        return HC_SUPERCEDE;
    }

    return HC_CONTINUE;
}

public GrenadeTouch(const grenade, const other) {
    if (!is_nullent(grenade)) {
        explodeNade(grenade);
    }
}

public GrenadeThink(const grenade) {
    if (!is_nullent(grenade)) {
        explodeNade(grenade);
    }
}

giveNade(const id) {
    new item = rg_get_player_item(id, ITEM_CLASSNAME, ITEM_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_entvar(item, var_classname, ITEM_CLASSNAME);

    set_entvar(item, var_HealthNade_Radius, Cvar(ExplodeRadius));
    set_entvar(item, var_HealthNade_ThrowHealingAmount, Cvar(ThrowHealingAmount));
    set_entvar(item, var_HealthNade_DrinkHealingAmount,  Cvar(DrinkHealingAmount));

    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, 4);
    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;
    }

    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 item, 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(3, 6));
    set_entvar(grenade, var_framerate, 1.0);
    set_entvar(grenade, var_gravity, 0.5);
    set_entvar(grenade, var_friction, 0.8);
    engfunc(EngFunc_SetModel, grenade, WORLDMODEL);

    copy_entvar(item, grenade, var_HealthNade_Radius);
    copy_entvar(item, grenade, var_HealthNade_ThrowHealingAmount);

    SetTouch(grenade, "GrenadeTouch");
    SetThink(grenade, "GrenadeThink");
    return grenade;
}

explodeNade(const grenade) {
    new Float:origin[3];
    get_entvar(grenade, var_origin, origin);

    new Float:fRadius = get_entvar(grenade, var_HealthNade_Radius);

    UTIL_BeamCylinder(origin, SpriteCylinder, 1, 5, 30, 1, {10, 255, 40}, 255, 5, fRadius);
    UTIL_CreateExplosion(origin, 65.0, SpriteExplode, 30, 20, (TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES));
    UTIL_SpriteTrail(origin, SpriteShape);

    rh_emit_sound2(grenade, 0, CHAN_WEAPON, SOUND_EXPLODE, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

    new id = get_entvar(grenade, var_owner);
    new team = get_member(id, m_iTeam);

    for (new player = 1, Float:playerOrigin[3]; player <= MaxClients; player++) {
        if (!is_user_alive(player) || get_member(player, m_iTeam) != team) {
            continue;
        }

        get_entvar(player, var_origin, playerOrigin);
        if (get_distance_f(origin, playerOrigin) < fRadius) {
            if (ExecuteHamB(Ham_TakeHealth, player, get_entvar(grenade, var_HealthNade_ThrowHealingAmount), DMG_GENERIC))
                UTIL_ScreenFade(player);
        }
    }

    destroyNade(grenade);
}

destroyNade(const grenade) {
    SetTouch(grenade, "");
    SetThink(grenade, "");
    set_entvar(grenade, var_flags, FL_KILLME);
}

InitCvars() {
    bind_pcvar_float(create_cvar(
        "HealthNade_ExplodeRadius", "300.0", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_EXPLODE_RADIUS"),
        true, 1.0
    ), Cvar(ExplodeRadius));

    bind_pcvar_float(create_cvar(
        "HealthNade_ThrowHealingAmount", "20.0", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_THROW_HEALING_AMOUNT")
    ), Cvar(ThrowHealingAmount));

    bind_pcvar_float(create_cvar(
        "HealthNade_DrinkHealingAmount", "35.0", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_DRINK_HEALING_AMOUNT")
    ), Cvar(DrinkHealingAmount));

    bind_pcvar_num(create_cvar(
        "HealthNade_Give", "1", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_GIVE")
    ), Cvar(Give));

    bind_pcvar_string(create_cvar(
        "HealthNade_Give_AccessFlags", "t", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_GIVE_ACCESS_FLAGS")
    ), Cvar(Give_AccessFlags), charsmax(Cvar(Give_AccessFlags)));

    bind_pcvar_string(create_cvar(
        "HealthNade_Drink_AccessFlags", "t", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_DRINK_ACCESS_FLAGS")
    ), Cvar(Drink_AccessFlags), charsmax(Cvar(Drink_AccessFlags)));

    bind_pcvar_num(create_cvar(
        "HealthNade_Give_MinRound", "1", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_GIVE_MIN_ROUND"),
        true, 1.0
    ), Cvar(Give_MinRound));

    bind_pcvar_float(create_cvar(
        "HealthNade_EquipDelay", "0.0", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_EQUIP_DELAY"),
        true, 0.0
    ), Cvar(EquipDelay));

    bind_pcvar_num(create_cvar(
        "HealthNade_ReplaceSmokegren", "0.0", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_REPLACE_SG"),
        true, 0.0, true, 1.0
    ), Cvar(ReplaceSmokegren));

    bind_pcvar_num(create_cvar(
        "HealthNade_Msg_UsageHint", "1", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_MSG_USAGE_HINT"),
        true, 0.0, true, 1.0
    ), Cvar(Msg_UsageHint));

    bind_pcvar_num(create_cvar(
        "HealthNade_Msg_FullHp", "1", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_MSG_FULL_HP"),
        true, 0.0, true, 1.0
    ), Cvar(Msg_FullHp));

    bind_pcvar_num(create_cvar(
        "HealthNade_NadeDrop", "2", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_NADE_DROP"),
        true, 0.0, true, 2.0
    ), Cvar(NadeDrop));

    bind_pcvar_num(create_cvar(
        "HealthNade_SlotId", "4", FCVAR_NONE,
        LangS("HEALTHNADE_CVAR_SLOT_ID"),
        true, 1.0, true, 5.0
    ), Cvar(SlotId));

    AutoExecConfig(true, "HealthNade");

    bind_pcvar_num(get_cvar_pointer("mp_nadedrops"), g_iCvarNadeDrops);
}

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 bool:IsBlind(const player) {
    return bool:(Float:get_member(player, m_blindUntilTime) > get_gametime());
}

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();
}

stock UTIL_ScreenFade(const player, const Float:fxTime = 1.0, const Float:holdTime = 0.3, const color[3] = {170, 255, 0}, const alpha = 80) {
    if (IsBlind(player)) {
        return;
    }

    const FFADE_IN = 0x0000;

    message_begin(MSG_ONE_UNRELIABLE, MsgIdScreenFade, .player = player);
    write_short(FixedUnsigned16(fxTime));
    write_short(FixedUnsigned16(holdTime));
    write_short(FFADE_IN);
    write_byte(color[0]);
    write_byte(color[1]);
    write_byte(color[2]);
    write_byte(alpha);
    message_end();
}

stock UTIL_BeamCylinder(const Float:origin[3], const sprite, const framerate, const life, const width, const amplitude, const color[3], const bright, const speed, const Float:size) {
    message_begin_f(MSG_PVS, SVC_TEMPENTITY, origin, 0);
    write_byte(TE_BEAMCYLINDER);
    write_coord_f(origin[0]);
    write_coord_f(origin[1]);
    write_coord_f(origin[2]);
    write_coord_f(origin[0]);
    write_coord_f(origin[1]);
    write_coord_f(origin[2] + size);
    write_short(sprite);
    write_byte(0);
    write_byte(framerate);
    write_byte(life);
    write_byte(width);
    write_byte(amplitude);
    write_byte(color[0]);
    write_byte(color[1]);
    write_byte(color[2]);
    write_byte(bright);
    write_byte(speed);
    message_end();
}

stock UTIL_CreateExplosion(const Float:origin[3], const Float:vecUp, const modelIndex, const scale, const frameRate, const flags) {
    message_begin_f(MSG_PVS, SVC_TEMPENTITY, origin, 0);
    write_byte(TE_EXPLOSION);
    write_coord_f(origin[0]);
    write_coord_f(origin[1]);
    write_coord_f(origin[2] + vecUp);
    write_short(modelIndex);
    write_byte(scale);
    write_byte(frameRate);
    write_byte(flags);
    message_end();
}

stock UTIL_SpriteTrail(Float:origin[3], const sprite, const cound = 20, const life = 20, const scale = 4, const noise = 20, const speed = 10) {
    message_begin(MSG_BROADCAST, SVC_TEMPENTITY); // MSG_PVS
    write_byte(TE_SPRITETRAIL);
    write_coord_f(origin[0]);
    write_coord_f(origin[1]);
    write_coord_f(origin[2] + 20.0);
    write_coord_f(origin[0]);
    write_coord_f(origin[1]);
    write_coord_f(origin[2] + 80.0);
    write_short(sprite);
    write_byte(cound);
    write_byte(life);
    write_byte(scale);
    write_byte(noise);
    write_byte(speed);
    message_end();
}

stock FixedUnsigned16(Float:value, scale = (1 << 12)) {
    return clamp(floatround(value * scale), 0, 0xFFFF);
}

bool:UserHasFlagsS(const UserId, const sFlags[], const bool:bStrict = false) {
    if (!sFlags[0]) {
        return true;
    }

    new iFlags = read_flags(sFlags);
    new iUserFlags = get_user_flags(UserId);

    return bStrict
        ? (iUserFlags & iFlags) == iFlags
        : (iUserFlags & iFlags) > 0;
}

public plugin_natives() {
    register_native("HealthNade_GiveNade", "_HealthNade_GiveNade");
}

public _HealthNade_GiveNade() {
    enum { player = 1 };
    new pPlayer = get_param(player);

    if(is_user_alive(pPlayer)) {
        return giveNade(pPlayer);
    }

    return NULLENT;
}
1 Ноя 2023
ImmortalAmxx, restart
1 Ноя 2023
Там, баг с этой ХП гранатой... Иногда GLOCK во 2-ом режими стреляет как со SH.
 
Сообщения
893
Реакции
149
Помог
25 раз(а)
sanjka095, если не ошибаюсь, при рестарте сервера сервер берет значения кваров из исходника, а при смене карты - уже из конфига.
Покажи квары настроек от хилки и от молотова.
 

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу