#include < amxmodx >
#include < fakemeta >
#include < hamsandwich >
#include < reapi >
#include < xs >
#define FAKE_MODEL // Менять ли модели грнаты в режиме мины
#define REMOVE_NOT_CONNECT // Удалять или активировать при выходе/смерти владельца гранаты
#define RADIUS_SENSOR 100.0 // Радиус срабатывания сенсорной мины
#define MOTION_SPEED 150.0 // Порог скорости срабатывания датчика движения
#if defined FAKE_MODEL
new const szFakeModels[][] = { // здесь можно настроить оружие, под которое будет замаскирована мина
"models/w_scout.mdl", "models/w_hegrenade.mdl", "models/w_usp.mdl",
"models/w_awp.mdl", "models/w_m4a1.mdl", "models/w_deagle.mdl", "models/w_ak47.mdl"
};
#endif
enum _:eExpType {
Norm, Touch, Mine, Sensor, InpulseE, Motion
};
new szExpName[eExpType][] = {
"Нормальный", "Столкновение", "Мина", "Сенсорная", "Взрыв на Е", "Датчик движения"
};
new g_iSensorSpr;
new const GrenadeClassNames[][] = {
"weapon_flashbang", "weapon_hegrenade", "weapon_smokegrenade"
};
public plugin_init()
{
register_plugin
(
"[AMXX] Grenade Mode",
"0.1",
"Flymic24"
);
for(new i; i < sizeof GrenadeClassNames; i++) {
RegisterHam(Ham_Item_Deploy, GrenadeClassNames[i], "HamHook_Item_Deploy", .Post = true);
RegisterHam(Ham_Weapon_SecondaryAttack, GrenadeClassNames[i], "HamHook_Item_SecondaryAttack", .Post = false);
RegisterHam(Ham_Spawn, GrenadeClassNames[i], "HamHook_Item_Spawn", .Post = false);
}
RegisterHookChain(RG_CBasePlayer_ThrowGrenade, "CBasePlayer_ThrowGrenade", .post = true);
RegisterHam(Ham_Think, "grenade", "HamHook_ThinkGrenade", .Post = false);
RegisterHam(Ham_Touch, "grenade", "HamHook_TouchGrenade", .Post = false);
}
public plugin_precache() {
g_iSensorSpr = precache_model("sprites/shockwave.spr");
}
public HamHook_Item_Deploy(const pItem) {
new iPlayer = get_member(pItem, m_pPlayer);
new iType = get_entvar(pItem, var_weapons);
client_print(iPlayer, print_center, "Режим: %s", szExpName[iType]);
}
public HamHook_Item_SecondaryAttack(const pItem) {
if (get_member(pItem, m_Weapon_flNextSecondaryAttack) > 0.0)
return HAM_IGNORED;
set_member(pItem, m_Weapon_flNextSecondaryAttack, 0.3);
new iPlayer = get_member(pItem, m_pPlayer);
new iType = get_entvar(pItem, var_weapons);
if (++iType >= eExpType) iType = Norm;
set_entvar(pItem, var_weapons, iType);
client_print(iPlayer, print_center, "Режим: %s", szExpName[iType]);
return HAM_IGNORED;
}
public CBasePlayer_ThrowGrenade(const pPlayer, const pWeapon, Float:vecSrc[3], Float:vecThrow[3], Float:time, const usEvent) {
new pGrenade = GetHookChainReturn(ATYPE_INTEGER);
if (is_nullent(pGrenade))
return HC_CONTINUE;
new iType = get_entvar(pWeapon, var_weapons);
set_entvar(pGrenade, var_weapons, iType);
new Float:fGameTime = get_gametime();
switch(iType) {
case Mine: {
set_entvar(pGrenade, var_solid, SOLID_TRIGGER);
set_entvar(pGrenade, var_dmgtime, fGameTime + 9999.0);
new Float:flAngles[3]; flAngles[1] = random_float(-360.0, 360.0);
set_entvar(pGrenade, var_angles, flAngles);
#if defined FAKE_MODEL
engfunc(EngFunc_SetModel, pGrenade, szFakeModels[random_num(0, charsmax(szFakeModels))]);
#endif
}
case InpulseE, Sensor, Motion: {
set_entvar(pGrenade, var_dmgtime, fGameTime + 9999.0);
set_entvar(pGrenade, var_teleport_time, fGameTime + 1.0);
}
}
return HC_CONTINUE;
}
public HamHook_Item_Spawn(const pItem) {
set_entvar(pItem, var_weapons, Norm);
}
public HamHook_TouchGrenade(const iEnt, const iToucher) {
new iType = get_entvar(iEnt, var_weapons);
new iOwner = get_entvar(iEnt, var_owner);
switch(iType) {
case Touch: {
return ActiveGrenade(iEnt);
}
case Mine: {
if (!is_user_alive(iToucher) || !is_user_alive(iOwner))
return HAM_IGNORED;
if (get_entvar(iEnt, var_flags) & FL_ONGROUND && get_member(iToucher, m_iTeam) != get_member(iOwner, m_iTeam))
return ActiveGrenade(iEnt);
}
}
return HAM_IGNORED;
}
public HamHook_ThinkGrenade(iEnt) {
new Float:fGameTime = get_gametime();
new iType = get_entvar(iEnt, var_weapons);
new iOwner = get_entvar(iEnt, var_owner);
if(!is_user_alive(iOwner)) {
#if defined REMOVE_NOT_CONNECT
set_entvar(iEnt, var_flags, get_entvar(iEnt, var_flags) | FL_KILLME);
return HAM_IGNORED;
#else
return ActiveGrenade(iEnt);
#endif
}
if (get_member(iEnt, m_Grenade_bDetonated))
return HAM_IGNORED;
switch(iType) {
case InpulseE: {
if (get_entvar(iOwner, var_button) & IN_USE) {
return ActiveGrenade(iEnt);
}
}
case Sensor, Motion: {
if (get_entvar(iEnt, var_flags) & FL_ONGROUND) {
new iOwnerTeam = get_member(iOwner, m_iTeam);
new _Victim = NULLENT;
new Float:fVecOrigin[3]; get_entvar(iEnt, var_origin, fVecOrigin);
new Float:fVecVelocity[3];
while ((_Victim = engfunc(EngFunc_FindEntityInSphere, _Victim, fVecOrigin, RADIUS_SENSOR)) != 0) {
if(!is_user_alive(_Victim)) continue;
if (get_member(_Victim, m_iTeam) == iOwnerTeam) continue;
if (iType == Motion) {
get_entvar(_Victim, var_velocity, fVecVelocity);
if (xs_vec_len(fVecVelocity) < MOTION_SPEED) continue;
}
return ActiveGrenade(iEnt);
}
if(get_entvar(iEnt, var_teleport_time) < fGameTime) {
MSG_TE_BEAMCYLINDER(fVecOrigin, iType != Motion ? {255, 100, 255} : {255, 0, 0});
set_entvar(iEnt, var_teleport_time, fGameTime + 1.0);
}
}
}
}
return HAM_IGNORED;
}
MSG_TE_BEAMCYLINDER(Float: fVecOrigin[3], RGB[3]) {
message_begin_f(MSG_BROADCAST, SVC_TEMPENTITY, fVecOrigin, 0);
write_byte(TE_BEAMCYLINDER);
write_coord_f(fVecOrigin[0]);
write_coord_f(fVecOrigin[1]);
write_coord_f(fVecOrigin[2]);
write_coord_f(fVecOrigin[0] + 30.0);
write_coord_f(fVecOrigin[1]);
write_coord_f(fVecOrigin[2] + RADIUS_SENSOR);
write_short(g_iSensorSpr);
write_byte(0);
write_byte(1);
write_byte(6);
write_byte(1);//hight
write_byte(1);
write_byte(RGB[0]);//red
write_byte(RGB[1]);//green
write_byte(RGB[2]);//blue
write_byte(255);
write_byte(0);
message_end();
}
ActiveGrenade(iEnt) {
if(get_member(iEnt, m_Grenade_bIsC4)) {
set_member(iEnt, m_Grenade_flC4Blow, 0.0);
}
else {
if (GetGrenadeType(iEnt) == WEAPON_SMOKEGRENADE)
set_entvar(iEnt, var_flags, get_entvar(iEnt, var_flags) | FL_ONGROUND);
set_entvar(iEnt, var_dmgtime, 0.0);
}
set_member(iEnt, m_Grenade_bDetonated, true);
dllfunc(DLLFunc_Think, iEnt);
return HAM_SUPERCEDE;
}