[GRENADE] Molotov 1.0.2

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
202
Реакции
-20
Ошибка
Нету
ОС
Linux
Amx Mod X
v1.10.0.5463
Билд
Protocol version 48
Exe version 1.1.2.7/Stdio (cstrike)
ReHLDS version: 3.11.0.777-dev
Build date: 21:17:20 Jun 29 2022 (3000)
Build from: https://github.com/dreamstalker/rehlds/commit/be0e1c8
ReGamedll
ReGameDLL version: 5.21.0.546-dev
Build date: 15:32:48 Dec 28 2021
Build from: https://github.com/s1lentq/ReGameDLL_CS/commit/09a6c61
Версия Metamod
Metamod-r v1.3.0.128, API (5:13)
Metamod-r build: 17:47:54 Aug 24 2018
Metamod-r from: https://github.com/theAsmodai/metamod-r/commit/0cf2f70
Список метамодулей
[ 1] SafeNameAndChat  RUN   -    SafeNameAndChat.so          v1.2 Beta 3        ini  ANY   ANY
[ 2] Reunion RUN - reunion_mm_i386.so v0.1.0.137 ini Start Never
[ 3] ReAuthCheck RUN - reauthcheck_mm_i386.so v0.1.6 ini Start Never
[ 4] Rechecker RUN - rechecker.so v2.7 ini Chlvl ANY
[ 5] WHBlocker RUN - whblocker_mm_i386.so v1.5.697 ini Chlvl ANY
[ 6] SmartGuard RUN - smartguard_mm_i386.so v1.3 ini ANY Never
[ 7] VoiceTranscoder RUN - VoiceTranscoder.so v2017RC5 ini ANY ANY
[ 8] ReSemiclip RUN - resemiclip_mm_i386.so v2.3.9 ini Chlvl ANY
[ 9] AMX Mod X RUN - amxmodx_mm_i386.so v1.10.0.5463 ini Start ANY
[10] AuthEmu RUN - authemu_amxx_i386.so v5.2.12.525-dev+m pl9 ANY Never
[11] CStrike RUN - cstrike_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[12] CSX RUN - csx_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[13] Engine RUN - engine_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[14] FakeMeta RUN - fakemeta_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[15] Fun RUN - fun_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[16] GeoIP RUN - geoip_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[17] Ham Sandwich RUN - hamsandwich_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[18] MySQL RUN - mysql_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[19] ReAimDetector RUN - reaimdetector_amxx_i386.so v0.2.2 pl9 ANY Never
[20] ReAPI RUN - reapi_amxx_i386.so v5.21.0.252-dev pl9 ANY Never
[21] SQLite RUN - sqlite_amxx_i386.so v1.10.0.5463 pl9 ANY ANY
[22] SxGeo RUN - sxgeo_amxx_i386.so v2.2 pl9 ANY Never
[23] VTC AMXX API RUN - VtcApi_amxx_i386.so v2017 RC2 pl9 ANY ANY
23 plugins, 23 running
Список плагинов
[  1] 0   GameCMS_API             5.6.1       zhorzh78          unknown                          gamecms.amx  running
[ 2] 1 Anti Sound ESP 0.2.181 s3zy unknown AntiSoundES running
[ 3] 2 ReAimDetector API 0.2.2 ReHLDS Team reaimdetect running
[ 4] 3 FreshBans 1.4.6b kanagava unknown fresh_bans. running
[ 5] 4 Advanced Rechecker 0.4 F@nt0M rechecker.a running
[ 6] 5 Aliases checker 1.0.6 kanagava unknown alias_detec running
[ 7] 6 HPPv6 Detector 1.0.6 Hy6 HPPv6_Detec running
[ 8] 7 cheater_cry 1.0.9 Hy6 cheater_cry running
[ 9] 8 [190] Ultimate Weapons 21.08.23BE SKAJIbnEJIb unknown ultimate_we running
[ 10] 9 [190] VIP RBS 21.08.23BE SKAJIbnEJIb unknown vip_rbs.amx running
[ 11] 10 [190] Ultimate Flags 21.03.24BE SKAJIbnEJIb unknown ultimate_fl running
[ 12] 11 Voice Manager 1.0 Hy6 voice_manag running
[ 13] 12 [190] MapChooser RBS 20.08.02 SKAJIbnEJIb & UF unknown mapchooser_ running
[ 14] 13 [190] Ultimate Informe 21.03.23 SKAJIbnEJIb unknown ultimate_in running
[ 15] 14 [190] Army Ranks Ultim 20.06.06 SKAJIbnEJIb unknown army_ranks_ running
[ 16] 15 [190] Ultimate Models 21.08.23BE SKAJIbnEJIb unknown ultimate_mo running
[ 17] 16 Menus Front-End 20.06.06 SKAJIbnEJIb & AM unknown amxmodmenu_ running
[ 18] 17 [190] BackWeapons RBS 20.06.06 SKAJIbnEJIb & ho unknown backweapons running
[ 19] 18 [190] DemoRecorder RBS 20.06.06 SKAJIbnEJIb unknown demorecorde running
[ 20] 19 [190] BonusMenu RBS 21.08.23BE SKAJIbnEJIb unknown bonusmenu_r running
[ 21] 20 [190] AR Pogony 20.06.06 SKAJIbnEJIb unknown ar_pogony.a running
[ 22] 21 [190] Damager RBS 20.06.06 SKAJIbnEJIb unknown damager_rbs running
[ 23] 22 [190] High Ping Kicker 20.06.06 SKAJIbnEJIb unknown hpk_rbs.amx running
[ 24] 23 [190] AC Spectator ESP 20.06.06 SKAJIbnEJIb & Ko unknown ac_esp.amxx running
[ 25] 24 [190] Parachute RBS 20.08.22BE SKAJIbnEJIb & KR unknown parachute_r running
[ 26] 25 [190] CmdMenu RBS 20.06.06 SKAJIbnEJIb & AM unknown cmdmenu_rbs running
[ 27] 26 [190] SlayLosers RBS 20.06.06 SKAJIbnEJIb & d3 unknown slaylosers_ running
[ 28] 27 [190] Kill Assist RBS 20.06.06 SKAJIbnEJIb & Di unknown killassist_ running
[ 29] 28 [190] AfkKicker RBS 21.08.22BE SKAJIbnEJIb unknown afkkicker_r running
[ 30] 29 [190] Top Award RBS 20.06.06 SKAJIbnEJIb unknown topaward_rb running
[ 31] 30 [190] Jobs RBS 21.08.23BE SKAJIbnEJIb unknown jobs_rbs.am running
[ 32] 31 [190] Chat RBS 20.10.24BE SKAJIbnEJIb unknown chat_rbs.am running
[ 33] 32 [190] AR Bets 20.06.06 SKAJIbnEJIb unknown ar_bets.amx running
[ 34] 33 [190] CsStats MySQL 21.08.22BE SKAJIbnEJIb unknown csstats_mys running
[ 35] 34 [190] Stats Configurat 20.06.06 SKAJIbnEJIb & AM unknown statscfg_rb running
[ 36] 35 [190] StatsX RBS 21.03.23 SKAJIbnEJIb & AM unknown statsx_rbs. running
[ 37] 36 Advanced Gag 1.9.0 neygomon amx_gag.amx running
[ 38] 37 Rock to Ban 1.02 Safety1st rock2ban.am running
[ 39] 38 Maps Menu 1.10.0.546 Hy6 mapsmenu.am running
[ 40] 39 Restrict Weapons 1.10.0.546 AMXX Dev Team restmenu.am running
[ 41] 40 Auto Team Balance Adva 1.5.1 Radius unknown auto_team_b running
[ 42] 41 [ReAPI] No Team Flash 0.0.3 Vaqtincha no_team_fla running
[ 43] 42 SpecList 1.2a FatalisDK speclist.am running
[ 44] 43 Reset Score 1.0 SKAJIbnEJIb reset_score running
[ 45] 44 GameCMS_Registration 1.5 zhorzh78 unknown gamecms_reg running
[ 46] 45 AWP Restrictions 1.5.1 Radius unknown awp_restric running
[ 47] 46 Last_players_sound 1.0 Ny6 last_player running
[ 48] 47 Weapon_Glow 0.0.1 Hy6 wp_glow.amx running
[ 49] 48 [ReAPI] Healthnade 0.0.2 F@nt0M healthnade. running
[ 50] 49 grenada_molotov 1.0.2 Hy6 grenade_mol running
[ 51] 50 Mode 2x2 2.5re s1lent mode.amxx running
[ 52] 51 [SxGeo] Connect Info 1.0 s1lent sxgeo_conne running
[ 53] 52 Style C4 Timer 3.1 OciXCrom crx_c4timer running
[ 54] 53 TimeLeft 1.10.0.546 AMXX Dev Team timeleft.am running
[ 55] 54 NextMap 1.10.0.546 AMXX Dev Team nextmap.amx running
[ 56] 55 Injector X 1.0 Deadly|Darkness dd_injector running
[ 57] 56 Weapon Model + Sound R 1.2 GHW_Chronic ghw.amxx running
[ 58] 57 Custom Smoke 1.07 bionext custom_smok running
[ 59] 58 ScreenMaker 1.1 neygomon screenmaker running
[ 60] 59 Revive Die Players 2.3.2 Emma Jule revive_team running
[ 61] 60 Players Menu 1.7 neugomon players_men running
[ 62] 61 Radio Block 1.0 Mmonster unknown radio.amxx running
[ 63] 62 game_name 1.0 Hy6 game_name.a running
[ 64] 63 Autoresponder/Advertis 0.5 MaximusBrood ad_manager. running
[ 65] 64 AuthEmu API 1.0 Dev-MS Team authemu.amx running
[ 66] 65 RC BaseChanger freesrv AMXX rc_basechan running
[ 67] 66 Master Servers Check 4.8 Hy6 ms_check.am running
[ 68] 67 Super_muzic 1.0 Hy6 welcome_mus running
[ 69] 68 [ReAPI] Ghost after de 0.0.2 Hy6 ghost.amxx running
[ 70] 69 amx_gore 1.6 Hy6 amx_gore.am running
[ 71] 70 Colored Spawn 1.2.2 Hy6 colored_spa running
[ 72] 71 vip_tab 1.0 Hy6 vip_tab.amx running
[ 73] 72 recoil_control 1.5 Hy6
Автор плагина
medusa
Версия плагина
1.0.2
Исходный код
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <reapi>
#include <xs>

#define PLUGIN_NAME "grenada_molotov"
#define PLUGIN_VERSION "1.0.2"
#define PLUGIN_AUTHOR "Hy6"

#define ALLOW_CUSTOMNADE

new const MOLOTOV_FIRE_CLASSNAME[] = "molotov";
new const EFFECT_CLASSNAME_MUZZLEFLASH[] = "weapon_molotov_muzzleflash";
new const EFFECT_CLASSNAME_WICK[] = "weapon_molotov_wick";
new const CLASSNAME_SMOKE_TOUCHER[] = "molotov_touch_smoke";

const WeaponIdType:WEAPON_ID = WEAPON_SMOKEGRENADE;

#if defined ALLOW_CUSTOMNADE
const WeaponIdType:WEAPON_NEW_ID = WEAPON_TMP;
#else
const WeaponIdType:WEAPON_NEW_ID = WEAPON_GLOCK;
#endif

const WeaponIdType:WEAPON_FAKE_ID = WeaponIdType:76;
new const WEAPON_NAME[] = "weapon_smokegrenade";
new const AMMO_NAME[] = "Molotov";
new const WEAPON_NEW_NAME[] = "/grenaderad/weapon_molotov";
new const ITEM_CLASSNAME[] = "weapon_molotov";
new const GRENADE_CLASSNAME[] = "grenade_molotov";
const AMMO_ID = 17;
const NUM_SLOT = 5;

const Float:MOLOTOV_PLAYTHINK_TIME = 0.04;

new MsgIdWeaponList, MsgIdAmmoPickup;
#if WEAPON_NEW_ID != WEAPON_GLOCK
new FwdRegUserMsg, MsgHookWeaponList;
#endif

new SpriteFireColumn, SpriteFireExplode, SpriteFireBall, SpriteFireGround;
new bool:bCreate[MAX_PLAYERS + 1];
new sizes[] = { 51, 51, 51 }, count = 3;

new const WEAPON_MODEL_VIEW_MOLOTOV[] = "models/grenaderad/v_molotov.mdl";
new const WEAPON_MODEL_PLAYER_MOLOTOV[] = "models/grenaderad/p_molotov.mdl";
new const WEAPON_MODEL_WORLD_MOLOTOV[] = "models/grenaderad/w_molotov.mdl";

new const MOLOTOV_MODEL_FLOOR[] = "models/grenaderad/molotov_fire_floor.mdl";

new const MOLOTOV_SPRITE_FIRE_BALL[] = "sprites/grenaderad/molotov_fire_ball.spr";
new const MOLOTOV_SPRITE_FIRE_COLUMN[] = "sprites/grenaderad/molotov_fire_column.spr";
new const MOLOTOV_SPRITE_FIRE_EXPLODE[] = "sprites/grenaderad/molotov_fire_explode_c.spr";
new const MOLOTOV_SPRITE_FIRE_GROUND[] = "sprites/grenaderad/molotov_fire_ground.spr";
new const MOLOTOV_SPRITE_XPARK1[] = "sprites/grenaderad/molotov_fire_blend_c.spr";
new const MOLOTOV_SPRITE_WICK[] = "sprites/grenaderad/molotov_wick.spr";

new const MOLOTOV_SOUND_EXPLODE[] = "weapons/grenaderad/molotov_explode.wav";
new const MOLOTOV_SOUND_HIT[] = "weapons/grenaderad/molotov_hit.wav";
new const MOLOTOV_SOUND_IDLE[] = "weapons/grenaderad/molotov_idle_loop.wav";
new const MOLOTOV_SOUND_LOOP[] = "weapons/grenaderad/molotov_fire_ground.wav";
new const MOLOTOV_SOUND_FADEOUT[] = "weapons/grenaderad/molotov_fire_fadeout.wav";
new const MOLOTOV_SOUND_EXT[] = "weapons/grenaderad/molotov_extinguish.wav";
new const GUNPICKUP_SOUND[] = "items/gunpickup2.wav";
new const AMMOPICKUP_SOUND[] = "items/9mmclip1.wav";

enum CvarStruct {
CVAR_BUY_ACCESS,
CVAR_EQUIP_ACCESS,
CVAR_CHECK_BUYZONE,
CVAR_COST,
CVAR_BUY_LIMIT,
CVAR_LIMIT_ROUND,
Float:CVAR_BUYTIME,
CVAR_HIT_PLAYER,
#if !defined ALLOW_CUSTOMNADE
CVAR_NADE_DROPS,
#endif
CVAR_KILLFEED,
Float:CVAR_RADIUS,
Float:CVAR_THROWTIME,
CVAR_DURATION,
CVAR_DEMAGE_MODE,
CVAR_DEMAGE_RADIUS_MODE,
Float:CVAR_DEMAGE_TIME,
Float:CVAR_DEMAGE_VALUE,
CVAR_EFFECT_MODE,
CVAR_EFFECT_NUM,
CVAR_SMOKE_TOUCH
}

new g_pCvarBuyAccess;
new g_pCvarSmokeOwner;
new g_eCvar[CvarStruct];
new BuyLimit[MAX_PLAYERS + 1];

new HookChain:HookChain_CBasePlayer_TakeDamage;
new HookChain:HookChain_deathNoticePostHook;

public plugin_precache() {
precache_model(WEAPON_MODEL_VIEW_MOLOTOV);
precache_model(WEAPON_MODEL_PLAYER_MOLOTOV);
precache_model(WEAPON_MODEL_WORLD_MOLOTOV);

if(get_cvar_num("sv_auto_precache_sounds_in_models") == 0) {
UTIL_PrecacheSoundsFromModel(WEAPON_MODEL_VIEW_MOLOTOV);
}
UTIL_PrecacheSpritesFromTxt(WEAPON_NEW_NAME);

#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

precache_model(MOLOTOV_MODEL_FLOOR);
precache_model(MOLOTOV_SPRITE_XPARK1);
precache_model(MOLOTOV_SPRITE_WICK);

precache_sound(MOLOTOV_SOUND_EXPLODE);
precache_sound(MOLOTOV_SOUND_HIT);
precache_sound(MOLOTOV_SOUND_IDLE);
precache_sound(MOLOTOV_SOUND_LOOP);
precache_sound(MOLOTOV_SOUND_FADEOUT);
precache_sound(MOLOTOV_SOUND_EXT);
precache_sound(GUNPICKUP_SOUND);
precache_sound(AMMOPICKUP_SOUND);

SpriteFireGround = precache_model(MOLOTOV_SPRITE_FIRE_GROUND);
SpriteFireBall = precache_model(MOLOTOV_SPRITE_FIRE_BALL);
SpriteFireColumn = precache_model(MOLOTOV_SPRITE_FIRE_COLUMN);
SpriteFireExplode = precache_model(MOLOTOV_SPRITE_FIRE_EXPLODE);
}

public plugin_init() {
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);

g_pCvarBuyAccess = create_cvar(
"molotov_buy_access", "", FCVAR_SERVER,
.description = "Флаги доступа для покупки или выдачи коктейля молотова (требует наличия вписанных; ^"^" - покупка доступна всем)."
);

bind_pcvar_num(
create_cvar(
"molotov_equip_access", "0", FCVAR_SERVER,
.description = "Автоматически выдавать коктейль молотова в начале раунда.",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 1.0
),
g_eCvar[CVAR_EQUIP_ACCESS]
);

bind_pcvar_num(
create_cvar(
"molotov_check_buyzone", "1", FCVAR_SERVER,
.description = "Проверка нахождения в зоне покупки.",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 1.0
),
g_eCvar[CVAR_CHECK_BUYZONE]
);

bind_pcvar_num(
create_cvar(
"molotov_cost", "800", FCVAR_SERVER,
.description = "Цена коктейля молотова.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_COST]
);

bind_pcvar_num(
create_cvar(
"molotov_buy_limit", "1", FCVAR_SERVER,
.description = "Сколько коктейлей молотова можно купить за одн раунд (значение: -1 убирает лимит).",
.has_min = true, .min_val = -1.0
),
g_eCvar[CVAR_BUY_LIMIT]
);

bind_pcvar_num(
create_cvar(
"molotov_limit_round", "3", FCVAR_SERVER,
.description = "С какого раунда после начала игры будет доступен молотов.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_LIMIT_ROUND]
);

bind_pcvar_num(
create_cvar(
"molotov_check_hit_player", "2", FCVAR_SERVER,
.description = "Сколько урона наносить при попадании коктейля молотова в тело игрока.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_HIT_PLAYER]
);

bind_pcvar_num(
create_cvar(
"molotov_killfeed", "1", FCVAR_SERVER,
.description = "Показывать ли в киллфиде рядом с именем приставку [ᴍᴏʟᴏᴛᴏᴠ].",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 1.0
),
g_eCvar[CVAR_KILLFEED]
);

bind_pcvar_float(
create_cvar(
"molotov_radius", "128.0", FCVAR_SERVER,
.description = "Радиус горения коктейля молотова.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_RADIUS]
);

bind_pcvar_float(
create_cvar(
"molotov_throwtime", "2.0", FCVAR_SERVER,
.description = "Сколько секунд коктейль молотова может находиться в полете перед взрывом.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_THROWTIME]
);

bind_pcvar_num(
create_cvar(
"molotov_duration", "12", FCVAR_SERVER,
.description = "Сколько секунд будет гореть коктейль молотова.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_DURATION]
);

bind_pcvar_num(
create_cvar(
"molotov_demage_mode", "1", FCVAR_SERVER,
.description = "Кто получает урон от коктейля молотова (0 - только противники, 1 - противники и игрок бросивший коктейль молотова, 2 - все игроки).",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 2.0
),
g_eCvar[CVAR_DEMAGE_MODE]
);

bind_pcvar_num(
create_cvar(
"molotov_demage_radius_mode", "2", FCVAR_SERVER,
.description = "Как будет наноситься урон от огня (1 - через Ham_TakeDamage [урон фиксированный в любой точке радиуса горения], 2 - через rg_dmg_radius [урон зависит от дальности к эпицентру горения и наличия брони]). ",
.has_min = true, .min_val = 1.0,
.has_max = true, .max_val = 2.0
),
g_eCvar[CVAR_DEMAGE_RADIUS_MODE]
);

bind_pcvar_float(
create_cvar(
"molotov_demage_time", "0.25", FCVAR_SERVER,
.description = "Переодичность нанесения урона.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_DEMAGE_TIME]
);

bind_pcvar_float(
create_cvar(
"molotov_demage_value", "20.0", FCVAR_SERVER,
.description = "Количество нанесенного урона за период (molotov_demage_time).",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_DEMAGE_VALUE]
);

bind_pcvar_num(
create_cvar(
"molotov_effect_mode", "2", FCVAR_SERVER,
.description = "Режим отрисовки спрайтов (1 - через Entities [env_sprite], 2 - через Temporary Entities [TE_SPRITE]).",
.has_min = true, .min_val = 1.0,
.has_max = true, .max_val = 2.0
),
g_eCvar[CVAR_EFFECT_MODE]
);

bind_pcvar_num(
create_cvar(
"molotov_effect_num", "40", FCVAR_SERVER,
.description = "Количество отрисовываемых спрайтов огня.",
.has_min = true, .min_val = 0.0
),
g_eCvar[CVAR_EFFECT_NUM]
);

bind_pcvar_num(
create_cvar(
"molotov_smoke_touch", "1", FCVAR_SERVER,
.description = "Тушить ли коктейль молотова дымовой гранатой.",
.has_min = true, .min_val = 0.0,
.has_max = true, .max_val = 1.0
),
g_eCvar[CVAR_SMOKE_TOUCH]
);

g_pCvarSmokeOwner = create_cvar(
"molotov_smoke_owner", "models/w_smokegrenade.mdl", FCVAR_SERVER,
.description = "Путь до модели дымовой гранаты. (Стандартная: models/w_smokegrenade.mdl)."
);

AutoExecConfig();

register_clcmd(WEAPON_NEW_NAME, "CmdSelect");

register_clcmd("molotov", "BuyMolotov_Cmd");

#if WEAPON_NEW_ID != WEAPON_GLOCK
RegisterHookChain(RG_CBasePlayer_HasRestrictItem, "CBasePlayer_RestrictItem_Pre", false)
#endif

RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "CBasePlayer_OnSpawnEquip_Post", true);
RegisterHookChain(RG_CBasePlayer_Killed, "CBasePlayer_Killed_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);

RegisterHam(Ham_Item_Deploy, WEAPON_NAME, "Item_Deploy_Post", true);
RegisterHam(Ham_Item_Holster, WEAPON_NAME, "Item_Holster_Post", true);
RegisterHam(Ham_Item_Holster, WEAPON_NAME, "Item_Holster_Pre", false);
RegisterHam(Ham_Weapon_PrimaryAttack, WEAPON_NAME, "Item_PrimaryAttack_Pre", false);

RegisterHookChain(RG_CBasePlayer_ThrowGrenade, "CBasePlayer_ThrowGrenade_Pre", false);

DisableHookChain((HookChain_CBasePlayer_TakeDamage = RegisterHookChain(RG_CBasePlayer_TakeDamage, "CBasePlayer_TakeDamage_Pre", false)));

RegisterHookChain(RG_CSGameRules_DeathNotice, "CSGameRules_DeathNotice_Pre", false);
DisableHookChain((HookChain_deathNoticePostHook = RegisterHookChain(RG_CSGameRules_DeathNotice, "CSGameRules_DeathNotice_Post", true)));

RegisterHookChain(RG_CGrenade_ExplodeSmokeGrenade, "CSGrenade_ExplodeSmokeGrenade_Pre", false);
RegisterHam(Ham_Think, "env_sprite", "FireMolotov_Think_Post", true);

new szAccess[24];
get_pcvar_string(g_pCvarBuyAccess, szAccess, charsmax(szAccess));
g_eCvar[CVAR_BUY_ACCESS] = read_flags(szAccess);

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, NUM_SLOT, WEAPON_NEW_ID,
ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE
);
#else
if (FwdRegUserMsg) {
unregister_forward(FM_RegUserMsg, FwdRegUserMsg, true);
}
unregister_message(MsgIdWeaponList, MsgHookWeaponList);
#endif
}


public OnConfigsExecuted() {
g_eCvar[CVAR_BUYTIME] = get_cvar_float("mp_buytime");
#if !defined ALLOW_CUSTOMNADE
g_eCvar[CVAR_NADE_DROPS] = get_cvar_num("mp_nadedrops");
#endif
}

public plugin_natives()
{
register_native("IsUserHasMolotov", "NativeIsUserHasMolotov", false);
register_native("GiveUserMolotov", "NativeGiveUserMolotov", false);
}

public NativeGiveUserMolotov(plugin, params)
{
enum { arg_player = 1 };

new id = get_param(arg_player);

if(!is_user_connected(id))
{
return false;
}

giveNade(id);

return true;
}

public NativeIsUserHasMolotov(plugin, params)
{
enum { arg_player = 1 };

new id = get_param(arg_player);

if(!is_user_connected(id))
{
return false;
}

return bool:(get_member(id, m_rgAmmo, AMMO_ID));
}

public BuyMolotov_Cmd(id) {
if (!is_user_alive(id)) {
return;
}

new Float: flCurTime = get_gametime();
new Float: flRoundStartTime = get_member_game(m_fRoundStartTime);
new bitAccess = g_eCvar[CVAR_BUY_ACCESS];

if (g_eCvar[CVAR_CHECK_BUYZONE] && !rg_get_user_buyzone(id)) {
return;
}

if (get_member(id, m_bIsVIP)) {
client_print(id, print_center, "#Cstrike_TitlesTXT_VIP_cant_buy");

return;
}

if (bitAccess && ~get_user_flags(id) & bitAccess){
client_print(id, print_center, "#Cstrike_TitlesTXT_Weapon_Not_Available");

return;
}

if(get_member_game(m_iTotalRoundsPlayed) + 1 < g_eCvar[CVAR_LIMIT_ROUND]){
client_print(id, print_center, "#Cstrike_TitlesTXT_Cant_buy");
return;
}

if(flCurTime - flRoundStartTime > g_eCvar[CVAR_BUYTIME] * 60 && g_eCvar[CVAR_BUYTIME] != -1){
client_print(id, print_center, "#Cstrike_TitlesTXT_Cant_buy");

return;
}

if(BuyLimit[id] == 0 && BuyLimit[id] != -1){
client_print(id, print_center, "#Cstrike_TitlesTXT_Already_Have_One");

return;
}

if(g_eCvar[CVAR_COST] && get_member(id, m_iAccount) < g_eCvar[CVAR_COST]) {
client_print(id, print_center, "#Cstrike_TitlesTXT_Not_Enough_Money");

return;
}

if(get_member(id, m_rgAmmo, AMMO_ID)) {
client_print(id, print_center, "#Cstrike_TitlesTXT_Cannot_Carry_Anymore");

return;
}

rg_add_account(id, -g_eCvar[CVAR_COST]);
rh_emit_sound2(id, 0, CHAN_ITEM, AMMOPICKUP_SOUND);
giveNade(id);
BuyLimit[id]--;
}

#if WEAPON_NEW_ID != WEAPON_GLOCK
public CBasePlayer_RestrictItem_Pre(id, ItemID:item, ItemRestType:iRestType) {
if(iRestType != ITEM_TYPE_BUYING) {
return HC_CONTINUE
}

if(item == ITEM_TMP) {
SetHookChainReturn(ATYPE_BOOL, true)
return HC_SUPERCEDE
}

return HC_CONTINUE
}
#endif

public CBasePlayer_OnSpawnEquip_Post(const id){
if(!is_user_connected(id))
return;

BuyLimit[id] = g_eCvar[CVAR_BUY_LIMIT];
new bitAccess = g_eCvar[CVAR_BUY_ACCESS];

if(g_eCvar[CVAR_EQUIP_ACCESS] < 1)
return;

if (bitAccess && ~get_user_flags(id) & bitAccess)
return;

if(get_member_game(m_iTotalRoundsPlayed) + 1 < g_eCvar[CVAR_LIMIT_ROUND])
return;


giveNade(id);
}

public CBasePlayer_Killed_Post(victim, attacker, inflictor){
if(!is_user_connected(victim)) return;

new activeItem = get_member(victim, m_pActiveItem);
if (!is_nullent(activeItem) && FClassnameIs(activeItem, ITEM_CLASSNAME) && get_entvar(victim, var_button) & IN_ATTACK && get_member(victim, m_rgAmmo, get_member(activeItem, m_Weapon_iPrimaryAmmoType)) > 0) {
new Float:origin[3], Float:view_ofs[3], Float:vecSrc[3], Float:vecThrow[3];
get_entvar(victim, var_origin, origin);
get_entvar(victim, var_view_ofs, view_ofs);
vecSrc[0] = origin[0] + view_ofs[0];
vecSrc[1] = origin[1] + view_ofs[1];
vecSrc[2] = origin[2] + view_ofs[2];
get_entvar(victim, var_angles, vecThrow);

throwNade(victim, activeItem, vecSrc, vecThrow, g_eCvar[CVAR_THROWTIME]);

new ammoIndex = get_member(activeItem, m_Weapon_iPrimaryAmmoType);
set_member(victim, m_rgAmmo, get_member(victim, m_rgAmmo, ammoIndex) - 1, ammoIndex);
set_member(activeItem, m_flStartThrow, 0.0);

Molotov_DeleteMuzzleFlash(activeItem);
}

#if !defined ALLOW_CUSTOMNADE
if(!get_member(victim, m_rgAmmo, AMMO_ID)) return;

switch(g_eCvar[CVAR_NADE_DROPS]){
case 1:
{
if(rg_get_player_item(victim, "weapon_hegrenade", GRENADE_SLOT) | rg_get_player_item(victim, "weapon_flashbang", GRENADE_SLOT) | rg_get_player_item(victim, "weapon_smokegrenade", GRENADE_SLOT))
return;

dropNade(victim);
}
case 2: dropNade(victim);
}
#endif
}

#if !defined ALLOW_CUSTOMNADE
dropNade(const other){
if(!is_user_connected(other)) return;

new dropnade = rg_create_entity("info_target", true);

if(is_nullent(dropnade))
return;

new Float: origin[3];
new Float: velocity[3];

ExecuteHam(Ham_Player_GetGunPosition, other, origin);

//get_entvar(other, var_origin, origin);

velocity[0] = random_float(-45.0, 45.0);
velocity[1] = random_float(-45.0, 45.0);

set_entvar(dropnade, var_classname, GRENADE_CLASSNAME);
engfunc(EngFunc_SetModel, dropnade, WEAPON_MODEL_WORLD_MOLOTOV);
set_entvar(dropnade, var_sequence, 0);
set_entvar(dropnade, var_movetype, MOVETYPE_TOSS);
set_entvar(dropnade, var_solid, SOLID_TRIGGER);
set_entvar(dropnade, var_velocity, velocity);
engfunc(EngFunc_SetOrigin, dropnade, origin);

SetTouch(dropnade, "Drop_ItemMolotov_Touch");
}
#endif

public CSGameRules_DeathNotice_Pre(victim, attacker, inflictor)
{
if(g_eCvar[CVAR_KILLFEED] == 0){
return;
}

if (!is_user_connected(attacker)){
return;
}

if(victim != attacker && inflictor != attacker && get_member(victim, m_bKilledByGrenade) && FClassnameIs(inflictor, MOLOTOV_FIRE_CLASSNAME)) {
new nameattacker[32], name[32];
get_entvar(attacker, var_netname, nameattacker, charsmax(nameattacker));

if(strlen(nameattacker) > 16) {
formatex(name, charsmax(name), "%.16s [ᴍᴏʟᴏᴛᴏᴠ]", nameattacker);
}else{
formatex(name, charsmax(name), "%s [ᴍᴏʟᴏᴛᴏᴠ]", nameattacker);}
message_begin(MSG_ALL, SVC_UPDATEUSERINFO);
write_byte(attacker - 1);
write_long(get_user_userid(attacker));
write_char('\');
write_char('n');
write_char('a');
write_char('m');
write_char('e');
write_char('\');
write_string(name);
for(new i = 0; i < 16; i++)
write_byte(0);
message_end();

EnableHookChain(HookChain_deathNoticePostHook);
}
}

public CSGameRules_DeathNotice_Post(victimEntIndex, killerEntIndex, inflictorEntIndex)
{
rh_update_user_info(killerEntIndex);
DisableHookChain(HookChain_deathNoticePostHook);
}



#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, _:GRENADE_SLOT - 1);
set_msg_arg_int(arg_position, ARG_BYTE, NUM_SLOT);
set_msg_arg_int(arg_flags, ARG_BYTE, ITEM_FLAG_LIMITINWORLD | ITEM_FLAG_EXHAUSTIBLE);

return PLUGIN_CONTINUE;
}
#endif

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

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

new MolotovFire = rg_find_ent_by_class(NULLENT, MOLOTOV_FIRE_CLASSNAME, false);
while (MolotovFire > 0) {
rh_emit_sound2(MolotovFire, 0, CHAN_STATIC, MOLOTOV_SOUND_LOOP, 0.0, ATTN_NONE, SND_STOP);
destroyNade(MolotovFire);
MolotovFire = rg_find_ent_by_class(MolotovFire, MOLOTOV_FIRE_CLASSNAME, false);
}

new SmokeTouch = rg_find_ent_by_class(NULLENT, CLASSNAME_SMOKE_TOUCHER, false);
while (SmokeTouch > 0) {
SetTouch(SmokeTouch, "");
SmokeTouch = rg_find_ent_by_class(SmokeTouch, CLASSNAME_SMOKE_TOUCHER, 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) {
if (FClassnameIs(item, ITEM_CLASSNAME)) {
SetHookChainArg(2, ATYPE_STRING, WEAPON_MODEL_VIEW_MOLOTOV);
SetHookChainArg(3, ATYPE_STRING, WEAPON_MODEL_PLAYER_MOLOTOV);
}

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

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

public Item_Holster_Pre(const item) {
new other = get_member(item, m_pPlayer);

rh_emit_sound2(other, 0, CHAN_WEAPON, MOLOTOV_SOUND_IDLE, 0.0, ATTN_NONE, SND_STOP);
}

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

while(!is_nullent(other)) {
Molotov_DeleteMuzzleFlash(item);

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

public Item_PrimaryAttack_Pre(item) {
if (is_nullent(item)) return;

new other = get_member(item, m_pPlayer);

if (FClassnameIs(item, ITEM_CLASSNAME) && Float: get_member(item, m_flStartThrow) + 0.5 < get_gametime() && get_member(item, m_flStartThrow)) {

if (bCreate[other]) {
return;
}

if (!bCreate[other]) {
Molotov_CreateMuzzleFlash(item, other, MOLOTOV_SPRITE_FIRE_COLUMN, 200.0, 25.0, 0.028, 3);
Molotov_CreateMuzzleFlash(item, other, MOLOTOV_SPRITE_FIRE_BALL, 180.0, 30.0, 0.035, 3);
Molotov_CreateMuzzleFlash(item, other, MOLOTOV_SPRITE_FIRE_BALL, 250.0, 25.0, 0.026, 4);
Molotov_CreateMuzzleFlash(item, other, MOLOTOV_SPRITE_XPARK1, 100.0, 1.0, 0.032, 4);

rh_emit_sound2(other, 0, CHAN_WEAPON, MOLOTOV_SOUND_IDLE, 0.5, 4.0);

bCreate[other] = true;
}
}

if (FClassnameIs(item, ITEM_CLASSNAME) && !Float: get_member(item, m_flStartThrow)) {
bCreate[other] = false;
}

}

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

rh_emit_sound2(id, 0, CHAN_WEAPON, MOLOTOV_SOUND_IDLE, 0.0, ATTN_NONE, SND_STOP);

new grenade = throwNade(id, item, vecSrc, vecThrow, g_eCvar[CVAR_THROWTIME]);
SetHookChainReturn(ATYPE_INTEGER, grenade);

Molotov_DeleteMuzzleFlash(item);

return HC_SUPERCEDE;
}


public FireMolotov_Think_Post(iEntity)
{
if (is_nullent(iEntity)) return;

set_entvar(iEntity, var_nextthink, get_gametime() + 0.025);
}

giveNade(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_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, NUM_SLOT);
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("grenade");
if (is_nullent(grenade) || is_nullent(item)) {
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_animtime, get_gametime());
set_entvar(grenade, var_sequence, random_num(2, 7));
set_entvar(grenade, var_framerate, 1.0);
set_entvar(grenade, var_gravity, 0.55);
set_entvar(grenade, var_friction, 0.8);
engfunc(EngFunc_SetModel, grenade, WEAPON_MODEL_WORLD_MOLOTOV);
set_entvar(grenade, var_dmgtime, get_gametime() + time);
set_entvar(grenade, var_nextthink, get_gametime() + 0.1);
set_member(grenade, m_Grenade_bIsC4, false);

Molotov_CreateWickFollow(grenade, MOLOTOV_SPRITE_WICK, 250.0, 25.0, 0.125);

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

return grenade;
}


public GrenadeTouch(const grenade, const other) {

if (is_nullent(grenade)) return;

if (FClassnameIs(other, "func_breakable") && get_entvar(other, var_spawnflags) != SF_BREAK_TRIGGER_ONLY)
dllfunc(DLLFunc_Use, other, grenade);

new owner = get_entvar(grenade, var_owner);

if (!is_nullent(other) && ExecuteHam(Ham_IsPlayer, other))
{
if (g_eCvar[CVAR_HIT_PLAYER]) {
ExecuteHamB(Ham_TakeDamage, other, grenade, owner, g_eCvar[CVAR_HIT_PLAYER], DMG_GRENADE);
}

set_entvar(grenade, var_dmgtime, 0.0);
set_entvar(grenade, var_nextthink, get_gametime() + 0.01);

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: origin[3];
new Float: vecPlaneNormal[3];

get_entvar(grenade, var_origin, origin);

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

engfunc(EngFunc_TraceLine, origin, vecEnd, IGNORE_MONSTERS, grenade, 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(grenade, var_dmgtime, 0.0);
set_entvar(grenade, var_nextthink, get_gametime() + 0.01);
}
else
rh_emit_sound2(grenade, 0, CHAN_VOICE, MOLOTOV_SOUND_HIT);

break;
}
}

public GrenadeThink(const grenade) {
if (is_nullent(grenade)) return;

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

if (engfunc(EngFunc_PointContents, origin) == CONTENTS_SKY)
{
set_entvar(grenade, var_flags, FL_KILLME);
destroyWick(grenade);
return;
}

set_entvar(grenade, var_nextthink, get_gametime() + 0.1);

if (Float: get_entvar(grenade, var_dmgtime) > get_gametime())
return;

explodeNade(grenade);
}



explodeNade(const grenade) {
if (is_nullent(grenade)) return;

new Float: flFraction;

new Float: vecEnd[3];
new Float: origin[3];
new Float: angles[3];

get_entvar(grenade, var_origin, origin);
get_entvar(grenade, var_angles, angles);

vecEnd = origin;
vecEnd[2] -= 64.0;

engfunc(EngFunc_TraceLine, origin, vecEnd, IGNORE_MONSTERS, grenade, 0);
get_tr2(0, TR_flFraction, flFraction);

if (flFraction >= 1.0)
{
UTIL_CreateExplosion(origin, Float: { 0.0, 0.0, 20.0 }, SpriteFireExplode, 16, 20, TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES);
rh_emit_sound2(grenade, 0, CHAN_STATIC, MOLOTOV_SOUND_EXPLODE);
destroyNade(grenade);
return;
}

if (engfunc(EngFunc_PointContents, origin) == CONTENTS_WATER)
{
new dropnade = rg_create_entity("info_target");

if (is_nullent(dropnade)) return;

set_entvar(dropnade, var_classname, GRENADE_CLASSNAME);
engfunc(EngFunc_SetModel, dropnade, WEAPON_MODEL_WORLD_MOLOTOV);
set_entvar(dropnade, var_sequence, 0);
set_entvar(dropnade, var_movetype, MOVETYPE_TOSS);
set_entvar(dropnade, var_solid, SOLID_TRIGGER);
set_entvar(dropnade, var_velocity, Float:{ 0.0, 0.0, 0.0 });
engfunc(EngFunc_SetOrigin, dropnade, origin);
set_entvar(dropnade, var_angles, angles);

SetTouch(dropnade, "Drop_ItemMolotov_Touch");

destroyNade(grenade);

return;
}

new owner = get_entvar(grenade, var_owner);

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

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

UTIL_CreateExplosion(origin, Float: { 0.0, 0.0, 0.0 }, SpriteFireExplode, 10, 20, TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES);
rh_emit_sound2(grenade, 0, CHAN_STATIC, MOLOTOV_SOUND_EXPLODE);

engfunc(EngFunc_VecToAngles, vecPlaneNormal, angles);

for (new i = 0; i < 3; i++)
origin[i] = vecEndPos[i] + vecPlaneNormal[i];

new EntMolotovRadius = rg_create_entity("info_target");

if (is_nullent(EntMolotovRadius))
return;

set_entvar(EntMolotovRadius, var_origin, origin);
set_entvar(EntMolotovRadius, var_angles, angles);
set_entvar(EntMolotovRadius, var_classname, MOLOTOV_FIRE_CLASSNAME);
set_entvar(EntMolotovRadius, var_solid, SOLID_TRIGGER);
set_entvar(EntMolotovRadius, var_movetype, MOVETYPE_TOSS);
set_entvar(EntMolotovRadius, var_iuser2, get_gametime() + g_eCvar[CVAR_DURATION]);
set_entvar(EntMolotovRadius, var_fuser1, get_gametime() + 0.3);
set_entvar(EntMolotovRadius, var_owner, owner);
engfunc(EngFunc_SetOrigin, EntMolotovRadius, origin);
engfunc(EngFunc_SetSize, EntMolotovRadius, Float:{-100.0, -100.0, -30.0}, Float:{100.0, 100.0, 30.0});

set_entvar(EntMolotovRadius, var_nextthink, get_gametime() + MOLOTOV_PLAYTHINK_TIME);

Molotov_CreateModelFloor(EntMolotovRadius, origin, angles, { 1, 15, 30 }, 1, g_eCvar[CVAR_DURATION]);

rh_emit_sound2(EntMolotovRadius, 0, CHAN_STATIC, MOLOTOV_SOUND_LOOP, 0.5);

SetThink(EntMolotovRadius, "ThinkFire");

if(g_eCvar[CVAR_SMOKE_TOUCH]){
SetTouch(EntMolotovRadius, "Molotov_TouchSmoke");
}

destroyNade(grenade);
}

public ThinkFire(EntMolotovRadius)
{
if (is_nullent(EntMolotovRadius))
return;

new Float: flCurTime = get_gametime();

static Float: origin[3];
get_entvar(EntMolotovRadius, var_origin, origin);

new owner = get_entvar(EntMolotovRadius, var_owner);

new Float: vecEnd[3];
vecEnd = origin;
vecEnd[2] += 32.0;

if (Float: get_entvar(EntMolotovRadius, var_dmgtime) <= flCurTime)
{
set_entvar(EntMolotovRadius, var_dmgtime, flCurTime + g_eCvar[CVAR_DEMAGE_TIME]);
EnableHookChain(HookChain_CBasePlayer_TakeDamage);

switch(g_eCvar[CVAR_DEMAGE_RADIUS_MODE]){
case 1:{
static iVictim = -1;
while((iVictim = engfunc(EngFunc_FindEntityInSphere, iVictim, origin, g_eCvar[CVAR_RADIUS])))
{
if(!is_user_alive(iVictim))continue;

ExecuteHamB(Ham_TakeDamage, iVictim, EntMolotovRadius, owner, g_eCvar[CVAR_DEMAGE_VALUE], DMG_GRENADE);
}
}
case 2: rg_dmg_radius(origin, EntMolotovRadius, owner, g_eCvar[CVAR_DEMAGE_VALUE], g_eCvar[CVAR_RADIUS], 0, DMG_GRENADE);
}

DisableHookChain(HookChain_CBasePlayer_TakeDamage);
}

if (get_entvar(EntMolotovRadius, var_fuser1) <= flCurTime)
{
UTIL_CreateExplosion(origin, Float: { 3.0, 3.0, 0.0 }, SpriteFireBall, 3, 20, TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES);
UTIL_CreateExplosion(origin, Float: { 6.0, 6.0, 0.0 }, SpriteFireColumn, 3, 20, TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES);
UTIL_CreateExplosion(origin, Float: { 0.0, 0.0, 0.0 }, SpriteFireBall, 5, 23, TE_EXPLFLAG_NODLIGHTS | TE_EXPLFLAG_NOSOUND | TE_EXPLFLAG_NOPARTICLES);

set_entvar(EntMolotovRadius, var_fuser1, get_gametime() + random_float(0.35, 0.45));
}

new iFireNum = get_entvar(EntMolotovRadius, var_iuser3);

if(iFireNum < g_eCvar[CVAR_EFFECT_NUM] / 10)
{
new Float: flFraction;

new Float: vecStart[3];
new Float: vecEnd[3];
new Float: vecAngles[3];
new Float: vecViewForward[3];
new Float: vecPlaneNormal[3];

get_entvar(EntMolotovRadius, var_vuser2, vecPlaneNormal);

vecAngles[0] = random_float(-(g_eCvar[CVAR_RADIUS] / 4), -g_eCvar[CVAR_RADIUS]);
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] = origin[i] + vecPlaneNormal[i] * (g_eCvar[CVAR_RADIUS] / 4);
vecEnd[i] = vecStart[i] + vecViewForward[i] * g_eCvar[CVAR_RADIUS];
}

engfunc(EngFunc_TraceLine, vecStart, vecEnd, IGNORE_MONSTERS, EntMolotovRadius, 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)
{
Molotov_CreateModelFloor(EntMolotovRadius, vecEnd, vecAngles, { 15, 30, 45 }, random_num(1, 25), random_num(g_eCvar[CVAR_DURATION] / 3, g_eCvar[CVAR_DURATION] - (g_eCvar[CVAR_DURATION] / 4)))
set_entvar(EntMolotovRadius, var_iuser3, iFireNum + 1);

UTIL_WorldDecal(vecEnd);
}
}

new iDebrisNum

if (g_eCvar[CVAR_EFFECT_MODE] == 1)
iDebrisNum = get_entvar(EntMolotovRadius, var_iuser4);

if (iDebrisNum < g_eCvar[CVAR_EFFECT_NUM])
{
new Float: flFraction;

new Float: vecStart[3];
new Float: vecEnd[3];
new Float: vecAngles[3];
new Float: vecViewForward[3];
new Float: vecPlaneNormal[3];

get_entvar(EntMolotovRadius, var_vuser1, vecPlaneNormal);

vecAngles[0] = random_float(-(g_eCvar[CVAR_RADIUS] / 4), -g_eCvar[CVAR_RADIUS]);
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] = origin[i] + vecPlaneNormal[i] * g_eCvar[CVAR_RADIUS] / 4;
vecEnd[i] = vecStart[i] + vecViewForward[i] * g_eCvar[CVAR_RADIUS];
}
engfunc(EngFunc_TraceLine, vecStart, vecEnd, IGNORE_MONSTERS, EntMolotovRadius, 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)
{
switch(g_eCvar[CVAR_EFFECT_MODE]){
case 1: set_entvar(EntMolotovRadius, var_iuser4, iDebrisNum + 1);
case 2: iDebrisNum++;
}

Molotov_CreateDebris(EntMolotovRadius, vecEnd);
}
}
else{
if(g_eCvar[CVAR_EFFECT_MODE] == 2) iDebrisNum = 0;
}

new MolotovFire = MaxClients + 1;

new Float:flDuration = get_entvar(EntMolotovRadius, var_iuser2);

if (flDuration <= get_gametime())
{
set_entvar(EntMolotovRadius, var_nextthink, get_gametime() + MOLOTOV_PLAYTHINK_TIME);
SetThink(EntMolotovRadius, "FireRemove");

rh_emit_sound2(EntMolotovRadius, 0, CHAN_STATIC, MOLOTOV_SOUND_LOOP, 0.0, ATTN_NONE, SND_STOP);
rh_emit_sound2(EntMolotovRadius, 0, CHAN_STATIC, MOLOTOV_SOUND_FADEOUT, 0.5);

return;
}

while ((MolotovFire = rg_find_ent_by_class(MolotovFire, MOLOTOV_FIRE_CLASSNAME)))
{
if (get_entvar(MolotovFire, var_owner) != EntMolotovRadius)
continue;

new Float:flDuration = get_entvar(get_entvar(MolotovFire, var_iuser1), var_iuser2);

new parts[3]; get_entvar(MolotovFire, var_vuser1, parts);

if (flDuration >= get_gametime())
{
for (new i = 0; i < count; i++)
{
parts[i]++;

if (parts[i] > 50)
parts[i] = 1;
}
}
else
{
for (new i = 0; i < count; i++)
{
if (parts[i] > 0)
parts[i]++;

if (parts[i] > 50)
parts[i] = 0;
}
}

set_entvar(MolotovFire, var_vuser1, parts);
set_entvar(MolotovFire, var_body, CalculateModelBodyArr(parts, sizes, count));
}

set_entvar(EntMolotovRadius, var_nextthink, get_gametime() + MOLOTOV_PLAYTHINK_TIME);
}


public FireRemove(EntMolotovRadius)
{
if (is_nullent(EntMolotovRadius))
return;

new MolotovFire = MaxClients + 1, bool:bRemove;

while ((MolotovFire = rg_find_ent_by_class(MolotovFire, MOLOTOV_FIRE_CLASSNAME)))
{
if (get_entvar(MolotovFire, var_owner) != EntMolotovRadius)
continue;

new parts[3]; get_entvar(MolotovFire, var_vuser1, parts);

for (new i = 0; i < count; i++)
{
if (parts[i] > 0)
parts[i]++;

if (parts[i] > 50)
parts[i] = 0;
}

set_entvar(MolotovFire, var_vuser1, parts);
set_entvar(MolotovFire, var_body, CalculateModelBodyArr(parts, sizes, count));

new Float:render = get_entvar(MolotovFire, var_renderamt);

if (render - 10.0 <= 0)
{
bRemove = true;
SetTouch(EntMolotovRadius, "");
set_entvar(MolotovFire, var_flags, FL_KILLME);
}
else
{
set_entvar(MolotovFire, var_renderamt, render - 10.0);
}

if (bRemove)
{
if((parts[0] | parts[1] | parts[2]) == 0)
{
set_entvar(MolotovFire, var_flags, FL_KILLME);
}
}
}

set_entvar(EntMolotovRadius, var_nextthink, get_gametime() + MOLOTOV_PLAYTHINK_TIME);
}

public CBasePlayer_TakeDamage_Pre(victim, inflictor, attacker, Float:flDamage, bitsDamageType)
{
if (!is_user_connected(victim)) {
return HC_SUPERCEDE;
}

if (FClassnameIs(inflictor, MOLOTOV_FIRE_CLASSNAME)) {
switch (g_eCvar[CVAR_DEMAGE_MODE]){
case 0: {
if (attacker == victim || get_member(attacker, m_iTeam) == get_member(victim, m_iTeam)){
SetHookChainReturn(ATYPE_INTEGER, true);
return HC_SUPERCEDE;
}
else return HC_CONTINUE;

}
case 1: {
if (attacker != victim && get_member(attacker, m_iTeam) == get_member(victim, m_iTeam)){
SetHookChainReturn(ATYPE_INTEGER, true);
return HC_SUPERCEDE;
}
else return HC_CONTINUE;
}
case 2: {
return HC_CONTINUE;
}
}
}

return HC_CONTINUE;
}

public Molotov_TouchSmoke(item, other)
{
if (is_nullent(item) || is_nullent(other)) return;

new ModelSmoke[64], SmokeOwner[64];
get_entvar(other, var_model, ModelSmoke, charsmax(ModelSmoke));
get_pcvar_string(g_pCvarSmokeOwner, SmokeOwner, charsmax(SmokeOwner));

if(equali(ModelSmoke, SmokeOwner))
{
set_entvar(other, var_flags, get_entvar(other, var_flags) | FL_ONGROUND);
set_entvar(other, var_dmgtime,0.0);
dllfunc(DLLFunc_Think,other);

new Float:origin[3];
get_entvar(other, var_origin, origin);

new MolotovFire = MaxClients + 1;

while((MolotovFire = engfunc(EngFunc_FindEntityInSphere, MolotovFire, origin, g_eCvar[CVAR_RADIUS])))
{
if(!FClassnameIs(MolotovFire, MOLOTOV_FIRE_CLASSNAME))
continue;

destroyEffect(MolotovFire)
set_entvar(MolotovFire, var_flags, FL_KILLME);
}

rh_emit_sound2(item, 0, CHAN_STATIC, MOLOTOV_SOUND_EXT);

destroyNade(item);

new SmokeRadius = rg_create_entity("info_target");

if (is_nullent(SmokeRadius))
return;

set_entvar(SmokeRadius, var_origin, origin);
set_entvar(SmokeRadius, var_classname, CLASSNAME_SMOKE_TOUCHER);
set_entvar(SmokeRadius, var_solid, SOLID_TRIGGER);
set_entvar(SmokeRadius, var_movetype, MOVETYPE_TOSS);
set_entvar(SmokeRadius, var_iuser2, get_gametime() + 20.0);
engfunc(EngFunc_SetOrigin, SmokeRadius, origin);
engfunc(EngFunc_SetSize, SmokeRadius, Float:{-100.0, -100.0, -30.0}, Float:{100.0, 100.0, 30.0});

SetTouch(SmokeRadius, "Molotov_TouchSmokeFire");
}
}

public Molotov_TouchSmokeFire(item, other)
{
if(is_nullent(item) || is_nullent(other)) return;

if(FClassnameIs(other, GRENADE_CLASSNAME))
{
set_entvar(other, var_flags, FL_KILLME);

rh_emit_sound2(other, 0, CHAN_STATIC, MOLOTOV_SOUND_EXT);
rh_emit_sound2(other, 0, CHAN_STATIC, MOLOTOV_SOUND_LOOP, 0.0, ATTN_NONE, SND_STOP);

destroyWick(other);
}

new Float:flDuration = get_entvar(item, var_iuser2);

if (flDuration <= get_gametime())
{
SetTouch(item, "");
return;
}
}

public CSGrenade_ExplodeSmokeGrenade_Pre(const this)
{
if (is_nullent(this)) return;

if(g_eCvar[CVAR_SMOKE_TOUCH]){

new SmokeRadius = rg_create_entity("info_target");

if (is_nullent(SmokeRadius))
return;

new Float:origin[3];
get_entvar(this, var_origin, origin);

set_entvar(SmokeRadius, var_origin, origin);
set_entvar(SmokeRadius, var_classname, CLASSNAME_SMOKE_TOUCHER);
set_entvar(SmokeRadius, var_solid, SOLID_TRIGGER);
set_entvar(SmokeRadius, var_movetype, MOVETYPE_TOSS);
set_entvar(SmokeRadius, var_iuser2, get_gametime() + 20.0);
engfunc(EngFunc_SetOrigin, SmokeRadius, origin);
engfunc(EngFunc_SetSize, SmokeRadius, Float:{-100.0, -100.0, -30.0}, Float:{100.0, 100.0, 30.0});

SetTouch(SmokeRadius, "Molotov_TouchSmokeFire");
}
}

public Drop_ItemMolotov_Touch(item, other)
{
if (is_nullent(item) || is_nullent(other)) return;

if (!ExecuteHam(Ham_IsPlayer, other)) return;

new bitAccess = g_eCvar[CVAR_BUY_ACCESS];

if (bitAccess && ~get_user_flags(other) & bitAccess)
return;

new ammo = rg_get_player_item(other, ITEM_CLASSNAME, GRENADE_SLOT);
if (ammo != 0) return;

giveNade(other);
rh_emit_sound2(other, 0, CHAN_ITEM, GUNPICKUP_SOUND);

set_entvar(item, var_flags, FL_KILLME);
}

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

set_entvar(grenade, var_flags, FL_KILLME);

destroyWick(grenade);
}

destroyWick(const grenade){
new item = MaxClients + 1;

while ((item = rg_find_ent_by_class(item, EFFECT_CLASSNAME_WICK)))
{
if (get_entvar(item, var_owner) != grenade)
continue;

if (!is_nullent(item))
set_entvar(item, var_flags, FL_KILLME);
}
}

destroyEffect(const grenade) {
new item = MaxClients + 1;

while ((item = rg_find_ent_by_class(item, MOLOTOV_FIRE_CLASSNAME)))
{
if (get_entvar(item, var_owner) != grenade)
continue;

if (!is_nullent(item))
set_entvar(item, var_flags, FL_KILLME);
}

rh_emit_sound2(grenade, 0, CHAN_STATIC, MOLOTOV_SOUND_LOOP, 0.0, ATTN_NONE, SND_STOP);
}


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_CreateExplosion(const Float: origin[3], const Float: vecOriginOffset[3] = { 0.0, 0.0, 0.0 }, const isModelIndex, const iScale, const iFrameRate, const iFlags)
{
message_begin_f(MSG_BROADCAST, SVC_TEMPENTITY, origin, 0);
write_byte(TE_EXPLOSION);
write_coord_f(origin[0] + vecOriginOffset[0]);
write_coord_f(origin[1] + vecOriginOffset[1]);
write_coord_f(origin[2] + vecOriginOffset[2]);
write_short(isModelIndex);
write_byte(iScale);
write_byte(iFrameRate);
write_byte(iFlags);
message_end();
}

stock UTIL_CreateSprite(const Float: origin[3], const isModelIndex, const iScale, const iAlpha)
{
message_begin_f(MSG_BROADCAST, SVC_TEMPENTITY, origin, 0);
write_byte(TE_SPRITE);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2]);
write_short(isModelIndex);
write_byte(iScale);
write_byte(iAlpha);
message_end();
}

stock Molotov_CreateModelFloor(owner, Float: origin[3], Float: angles[3], parts[3], sequence, time)
{
if (is_nullent(owner)) return;

new Float: flFraction;

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

vecEndPos = origin;
vecEndPos[2] -= 256.0;

engfunc(EngFunc_TraceLine, origin, vecEndPos, IGNORE_MONSTERS, owner, 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++)
origin[i] = vecEndPos[i] + vecPlaneNormal[i];

FloorOriginAngles(origin, angles);

new MolotovFire = rg_create_entity("info_target", false);

if (is_nullent(MolotovFire)) return;

set_entvar(MolotovFire, var_classname, MOLOTOV_FIRE_CLASSNAME);
set_entvar(MolotovFire, var_owner, owner);
engfunc(EngFunc_SetOrigin, MolotovFire, origin);
engfunc(EngFunc_SetModel, MolotovFire, MOLOTOV_MODEL_FLOOR);
set_entvar(MolotovFire, var_angles, angles);
set_entvar(MolotovFire, var_sequence, sequence);
set_entvar(MolotovFire, var_rendermode, kRenderTransAdd);
set_entvar(MolotovFire, var_renderamt, 255.0);
set_entvar(MolotovFire, var_vuser1, parts);
set_entvar(MolotovFire, var_iuser1, MolotovFire);
set_entvar(MolotovFire, var_iuser2, get_gametime() + time);

dllfunc(DLLFunc_Spawn, MolotovFire);
}

stock Molotov_CreateDebris(owner, Float: origin[3])
{
if (is_nullent(owner)) return;

new Float: flFraction;

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

vecEndPos = origin;
vecEndPos[2] -= 256.0;

engfunc(EngFunc_TraceLine, origin, vecEndPos, IGNORE_MONSTERS, owner, 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++)
origin[i] = vecEndPos[i] + vecPlaneNormal[i];

vecAngles[0] = -vecAngles[0] + 180.0;
vecAngles[2] = -vecAngles[2] + 180.0;

switch(g_eCvar[CVAR_EFFECT_MODE]){
case 1:
{
new iFire = rg_create_entity("env_sprite", true);

if (is_nullent(iFire))
return;

set_entvar(iFire, var_classname, MOLOTOV_FIRE_CLASSNAME);
set_entvar(iFire, var_origin, origin);
set_entvar(iFire, var_angles, vecAngles);
set_entvar(iFire, var_model, MOLOTOV_SPRITE_FIRE_GROUND);
set_entvar(iFire, var_spawnflags, SF_SPRITE_STARTON);
set_entvar(iFire, var_owner, owner);
set_entvar(iFire, var_rendermode, kRenderTransAdd);
set_entvar(iFire, var_renderamt, 255.0);
set_entvar(iFire, var_framerate, 12.0);
set_entvar(iFire, var_scale, 0.5);
dllfunc(DLLFunc_Spawn, iFire);
}
case 2: UTIL_CreateSprite(origin, SpriteFireGround, random_num(5,7), 255);
}
}

stock Molotov_CreateMuzzleFlash(item, other, const models[], Float:renderamt, Float:frame, Float:scale, body)
{
if (is_nullent(item)) return;

new iMuzzleFlash = rg_create_entity("env_sprite", true);

if (is_nullent(iMuzzleFlash)) return;

set_entvar(iMuzzleFlash, var_model, models);
set_entvar(iMuzzleFlash, var_classname, EFFECT_CLASSNAME_MUZZLEFLASH);
set_entvar(iMuzzleFlash, var_spawnflags, SF_SPRITE_STARTON);
set_entvar(iMuzzleFlash, var_rendermode, kRenderTransAdd);
set_entvar(iMuzzleFlash, var_renderamt, renderamt);
set_entvar(iMuzzleFlash, var_framerate, frame);
set_entvar(iMuzzleFlash, var_scale, scale);
set_entvar(iMuzzleFlash, var_owner, other);
set_entvar(iMuzzleFlash, var_aiment, other);
set_entvar(iMuzzleFlash, var_body, body);
dllfunc(DLLFunc_Spawn, iMuzzleFlash);
}

stock Molotov_CreateWickFollow(other, const models[], Float:renderamt, Float:frame, Float:scale)
{
new iWickFollow = rg_create_entity("env_sprite", true);

if (is_nullent(iWickFollow)) return;

set_entvar(iWickFollow, var_model, models);
set_entvar(iWickFollow, var_classname, EFFECT_CLASSNAME_WICK);
set_entvar(iWickFollow, var_spawnflags, SF_SPRITE_STARTON);
set_entvar(iWickFollow, var_rendermode, kRenderTransAdd);
set_entvar(iWickFollow, var_renderamt, renderamt);
set_entvar(iWickFollow, var_framerate, frame);
set_entvar(iWickFollow, var_scale, scale);
set_entvar(iWickFollow, var_owner, other);
set_entvar(iWickFollow, var_aiment, other);
dllfunc(DLLFunc_Spawn, iWickFollow);
}

stock Molotov_DeleteMuzzleFlash(other)
{
new item = MaxClients + 1;

while ((item = rg_find_ent_by_class(item, EFFECT_CLASSNAME_MUZZLEFLASH)))
{
if (get_entvar(item, var_owner) != get_entvar(other, var_owner))
continue;

if (!is_nullent(item))
set_entvar(item, var_flags, FL_KILLME);
}
}

stock UTIL_WorldDecal(Float:origin[3])
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_WORLDDECAL);
write_coord_f(origin[0]);
write_coord_f(origin[1]);
write_coord_f(origin[2]);
write_byte(engfunc(EngFunc_DecalIndex, "{ding10"));
message_end();
}

stock bool:rg_get_user_buyzone(const other) {
new bitSignals[UnifiedSignals];
get_member(other, m_signals, bitSignals);

return bool:(SignalState:bitSignals[US_State] & SIGNAL_BUY);
}

public CalculateModelBodyArr(const parts[], const sizes[], const count) {
static bodyInt32 = 0, temp = 0, it = 0, tempCount; bodyInt32 = 0; tempCount = count;
while (tempCount--) {
if (sizes[tempCount] == 1) continue;
temp = parts[tempCount]; for (it = 0; it < tempCount; it++) temp *= sizes[it];
bodyInt32 += temp;
}
return bodyInt32;
}

new const Float:SubFloat[3] = { 0.0, 0.0, 9999.0 };
stock FloorOriginAngles(Float:flOrigin[3], Float:fAngles[3]) {
static Float:traceto[3], Float:fraction, Float:original_forward[3], Float:angles2[3], Float:right[3], Float:up[3], Float:fwd[3];
new iTrace = create_tr2(); if (!iTrace) return;
xs_vec_sub(flOrigin, SubFloat, traceto);
engfunc(EngFunc_TraceLine, flOrigin, traceto, IGNORE_MONSTERS | IGNORE_MISSILE, 0, iTrace);
get_tr2(iTrace, TR_flFraction, fraction);
if (fraction == 1.0) { free_tr2(iTrace); return; }
angle_vector(fAngles, ANGLEVECTOR_FORWARD, original_forward);
get_tr2(iTrace, TR_vecPlaneNormal, up); free_tr2(iTrace);
xs_vec_cross(original_forward, up, right);
xs_vec_cross(up, right, fwd);
vector_to_angle(fwd, fAngles);
vector_to_angle(right, angles2);
fAngles[2] = -1.0 * angles2[0];
}

stock UTIL_PrecacheSoundsFromModel(const szModelPath[])
{
new iFile;

if ((iFile = fopen(szModelPath, "rt")))
{
new szSoundPath[64];

new iNumSeq, iSeqIndex;
new iEvent, iNumEvents, iEventIndex;

fseek(iFile, 164, SEEK_SET);
fread(iFile, iNumSeq, BLOCK_INT);
fread(iFile, iSeqIndex, BLOCK_INT);

for (new k, i = 0; i < iNumSeq; i++)
{
fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
fread(iFile, iNumEvents, BLOCK_INT);
fread(iFile, iEventIndex, BLOCK_INT);
fseek(iFile, iEventIndex + 176 * i, SEEK_SET);

for (k = 0; k < iNumEvents; k++)
{
fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
fread(iFile, iEvent, BLOCK_INT);
fseek(iFile, 4, SEEK_CUR);

if (iEvent != 5004)
continue;

fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);

if (strlen(szSoundPath))
{
strtolower(szSoundPath);
engfunc(EngFunc_PrecacheSound, szSoundPath);
}
}
}
}

fclose(iFile);
}

stock UTIL_PrecacheSpritesFromTxt(const szWeaponList[])
{
new szTxtDir[64], szSprDir[64];
new szFileData[128], szSprName[48], temp[1];

format(szTxtDir, charsmax(szTxtDir), "sprites/%s.txt", szWeaponList);
engfunc(EngFunc_PrecacheGeneric, szTxtDir);

new iFile = fopen(szTxtDir, "rb");
while (iFile && !feof(iFile))
{
fgets(iFile, szFileData, charsmax(szFileData));
trim(szFileData);

if (!strlen(szFileData))
continue;

new pos = containi(szFileData, "640");

if (pos == -1)
continue;

format(szFileData, charsmax(szFileData), "%s", szFileData[pos + 3]);
trim(szFileData);

strtok(szFileData, szSprName, charsmax(szSprName), temp, charsmax(temp), ' ', 1);
trim(szSprName);

format(szSprDir, charsmax(szSprDir), "sprites/%s.spr", szSprName);
engfunc(EngFunc_PrecacheGeneric, szSprDir);
}

if (iFile) fclose(iFile);
}
Всем привет проблема такая. Включаю данный плагин и не работает вип меню от Скальпиля. Просто не выходит само меню. Кто подскажет в чём проблема? Ошибок нет и краша тоже нет. Проблема только в одном. Не работает вип меню.
 
В этой теме было размещено решение! Перейти к решению.
Сообщения
202
Реакции
-20
Я отключил его потому что меню не работает. Могу включить и вставить сюда.
8 Июл 2022
Конфиг от плагина надо?
 
Сообщения
202
Реакции
-20
Я уже поставил список и вывел сюда.
50 сразу за хилкой. Не правильно стоит?
8 Июл 2022
Его выше вип меню надо ставить?
 
Сообщения
202
Реакции
-20
Сменил автора не могу сейчас заменить список плагинов.
8 Июл 2022
И выше ставил и ниже не работает меню.
 
Сообщения
1,496
Реакции
1,496
Помог
2 раз(а)
После 100й строки кода + -.сразу понятно чей плагин.
Медуза Всем Вам просто так подарил это дело,что -бы потом он не был автором?
Пипец просто...как так можно...😟
 
Сообщения
202
Реакции
-20
Проблема в конфиге в этой строчке.
// Автоматически выдавать коктейль молотова в начале раунда.
// -
// Default: "0"
// Minimum: "0.000000"
// Maximum: "1.000000"
molotov_equip_access "0"

Если ставишь 1 то меню пропадает.
 
Статус
В этой теме нельзя размещать новые ответы.

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

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