Code:
#include <amxmodx>
#include <cstrike>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
// Не трогать
const pDataKey_iPlayerItems = 367;
const pData_Player = 5;
const pDataKey_iNext = 42;
const pDataKey_iId = 43;
const OFFSET_CURWEAPON = 373;
const OFFSET_OWNER_GUN = 41;
const OFFSET_BLOCK_PLAYER = 4;
const MAX_GRENADES = 4;
const TASK_GRENADE_ACTIVE = 0x6588;
const TYPE_NONE = 0;
const TYPE_ONE = 1;
const TYPE_TWO = 2;
const TYPE_THREE = 3;
// Не трограть
const DIST_EFFECT = 350; // Дистанция работы эффектов
new g_iMode[33], g_iSprite, g_iColorSprite[3], bool: g_bIsUse[33];
new const GRENADES_LIST[][] =
{
"Дымовая",
"Восстанавливающая здоровья",
"Восстанавливающая патроны",
"Шокирующая"
}
new const GRENADE_MODEL_VIEW[MAX_GRENADES][] =
{
"models/v_smokegrenade.mdl",
"models/grenade_modes/v_health_bomb.mdl",
"models/grenade_modes/v_ammo_bomb.mdl",
"models/grenade_modes/v_drop_bomb.mdl"
};
new const GRENADE_MODEL_WEAPON[MAX_GRENADES][] =
{
"models/p_smokegrenade.mdl",
"models/grenade_modes/p_health_bomb.mdl",
"models/grenade_modes/p_ammo_bomb.mdl",
"models/grenade_modes/p_drop_bomb.mdl"
};
new const GRENADE_MODEL_WORLD[MAX_GRENADES][] =
{
"models/w_smokegrenade.mdl",
"models/grenade_modes/w_health_bomb.mdl",
"models/grenade_modes/w_ammo_bomb.mdl",
"models/grenade_modes/w_drop_bomb.mdl"
};
public plugin_precache()
{
for(new i; i < MAX_GRENADES; i++)
{
precache_model(GRENADE_MODEL_VIEW[i]);
precache_model(GRENADE_MODEL_WEAPON[i]);
precache_model(GRENADE_MODEL_WORLD[i]);
}
g_iSprite = precache_model("sprites/zbeam3.spr");
g_iColorSprite[0] = precache_model("sprites/grenade_modes/green.spr");
g_iColorSprite[1] = precache_model("sprites/grenade_modes/gray.spr");
g_iColorSprite[2] = precache_model("sprites/grenade_modes/blue.spr");
}
public plugin_init()
{
register_plugin("SmokeGren Mode", "1.0", "EpisCape");
RegisterHam(Ham_Item_Deploy, "weapon_smokegrenade", "fwHam_DeploySmoke_Post", true);
register_forward(FM_SetModel, "fwd_SetModel_Post", true);
register_think("grenade", "GrenadeThink");
}
public client_putinserver(id)
{
g_bIsUse[id] = false;
g_iMode[id] = TYPE_NONE;
}
public client_PreThink(id)
{
if(!is_user_alive(id))
return;
if(~entity_get_int(id, EV_INT_button) & IN_ATTACK2)
return;
if(entity_get_int(id, EV_INT_oldbuttons) & IN_ATTACK2)
return;
if(get_user_weapon(id) != CSW_SMOKEGRENADE)
return;
static Float: fTime, Float: fNextTime[33];
fTime = get_gametime();
if(fNextTime[id] < fTime)
{
if(!g_bIsUse[id])
{
client_print(id, print_center, "Режим гранаты: %s", GRENADES_LIST[g_iMode[id] += g_iMode[id] < TYPE_THREE ? TYPE_ONE : -TYPE_THREE]);
ExecuteHamB(Ham_Item_Deploy, get_pdata_cbase(id, OFFSET_CURWEAPON));
}
fNextTime[id] = fTime + 0.5;
}
}
public fwHam_DeploySmoke_Post(id)
{
if(!is_valid_ent(id))
return;
if(!is_user_alive((id = get_pdata_cbase(id, OFFSET_OWNER_GUN, OFFSET_BLOCK_PLAYER))))
return;
entity_set_string(id, EV_SZ_viewmodel, GRENADE_MODEL_VIEW[g_iMode[id]]);
entity_set_string(id, EV_SZ_weaponmodel, GRENADE_MODEL_WEAPON[g_iMode[id]]);
}
public fwd_SetModel_Post(iEnt, sModel[])
{
if(!is_valid_ent(iEnt))
return FMRES_IGNORED;
if(!equali(sModel, "models/w_smokegrenade.mdl"))
return FMRES_IGNORED;
new iOwner = entity_get_edict(iEnt, EV_ENT_owner);
if(!is_user_alive(iOwner))
return FMRES_IGNORED;
switch(g_iMode[iOwner])
{
case TYPE_NONE: return FMRES_IGNORED;
case TYPE_ONE: trail_msg(iEnt, 128, 255, 0);
case TYPE_TWO: trail_msg(iEnt, 128, 128, 64);
case TYPE_THREE: trail_msg(iEnt, 128, 128, 128);
}
g_bIsUse[iOwner] = true;
set_task(1.6, "Grenade_Active", TASK_GRENADE_ACTIVE + iEnt);
entity_set_model(iEnt, GRENADE_MODEL_WORLD[g_iMode[iOwner]]);
return FMRES_SUPERCEDE;
}
public Grenade_Active(iEnt)
{
iEnt -= TASK_GRENADE_ACTIVE;
if(!is_valid_ent(iEnt))
return;
new iOwner = entity_get_edict(iEnt, EV_ENT_owner);
if(!is_user_alive(iOwner))
return;
new Float: fOrigin[3]
entity_get_vector(iEnt, EV_VEC_origin, fOrigin);
g_bIsUse[iOwner] = false;
switch(g_iMode[iOwner])
{
case TYPE_ONE: CreateBeamCylinder(fOrigin, 128, 255, 0);
case TYPE_TWO: CreateBeamCylinder(fOrigin, 128, 128, 64);
case TYPE_THREE: CreateBeamCylinder(fOrigin, 128, 128, 128);
}
CreateEffect(iOwner, fOrigin, g_iMode[iOwner]);
CreateExplode(iOwner, fOrigin, g_iMode[iOwner]);
entity_set_int(iEnt, EV_INT_flags, entity_get_int(iEnt, EV_INT_flags) | FL_KILLME);
}
public GrenadeThink(iEnt)
{
if(!is_valid_ent(iEnt))
return PLUGIN_CONTINUE;
static sModel[32];
entity_get_string(iEnt, EV_SZ_model, sModel, charsmax(sModel));
if(!equal(sModel, "models/w_smokegrenade.mdl") && g_iMode[entity_get_edict(iEnt, EV_ENT_owner)])
return PLUGIN_HANDLED;
return PLUGIN_CONTINUE;
}
public trail_msg(iEnt, r, g, b)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BEAMFOLLOW);
write_short(iEnt);
write_short(g_iSprite);
write_byte(50);
write_byte(8);
write_byte(r);
write_byte(g);
write_byte(b);
write_byte(150);
message_end();
}
public CreateBeamCylinder(Float: fOrigin[3], r, g, b)
{
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, fOrigin, 0);
write_byte(TE_BEAMCYLINDER);
engfunc(EngFunc_WriteCoord, fOrigin[0]);
engfunc(EngFunc_WriteCoord, fOrigin[1]);
engfunc(EngFunc_WriteCoord, fOrigin[2]);
engfunc(EngFunc_WriteCoord, fOrigin[0]);
engfunc(EngFunc_WriteCoord, fOrigin[1]);
engfunc(EngFunc_WriteCoord, fOrigin[2] + DIST_EFFECT);
write_short(g_iSprite);
write_byte(0);
write_byte(0);
write_byte(4);
write_byte(60);
write_byte(0);
write_byte(r);
write_byte(g);
write_byte(b);
write_byte(1000);
write_byte(0);
message_end();
}
public CreateExplode(id, Float: fOrigin[3], iType)
{
message_begin(MSG_ALL,SVC_TEMPENTITY, {0,0,0}, id);
write_byte(TE_SPRITETRAIL);
engfunc(EngFunc_WriteCoord, fOrigin[0]);
engfunc(EngFunc_WriteCoord, fOrigin[1]);
engfunc(EngFunc_WriteCoord, fOrigin[2] + 20);
engfunc(EngFunc_WriteCoord, fOrigin[0]);
engfunc(EngFunc_WriteCoord, fOrigin[1]);
engfunc(EngFunc_WriteCoord, fOrigin[2] + 80);
write_short(g_iColorSprite[iType-1]);
write_byte(20);
write_byte(20);
write_byte(4);
write_byte(20);
write_byte(10);
message_end();
}
public CreateEffect(id, Float: fOrigin[3], iType)
{
new iVictim = FM_NULLENT;
while((iVictim = find_ent_in_sphere(iVictim, fOrigin, float(DIST_EFFECT))))
{
if(!is_user_alive(iVictim))
continue;
switch(iType)
{
case TYPE_ONE:
{
if(get_user_team(id) == get_user_team(iVictim))
entity_set_float(iVictim, EV_FL_health, 100.0);
}
case TYPE_TWO:
{
if(get_user_team(id) == get_user_team(iVictim))
set_user_bpammo(iVictim);
}
case TYPE_THREE:
{
if(get_user_team(id) != get_user_team(iVictim))
{
DropWeapon(iVictim, 1);
DropWeapon(iVictim, 2);
}
}
}
}
}
public set_user_bpammo(id)
{
static iWeapon; iWeapon = get_user_weapon(id);
static iAmmo;
switch(iWeapon)
{
case CSW_AK47, CSW_AUG, CSW_FAMAS, CSW_GALIL, CSW_M4A1, CSW_SCOUT, CSW_SG550, CSW_G3SG1, CSW_SG552: iAmmo = 90;
case CSW_P228: iAmmo = 52;
case CSW_M3, CSW_XM1014: iAmmo = 32;
case CSW_MAC10, CSW_FIVESEVEN, CSW_UMP45, CSW_USP, CSW_P90: iAmmo = 100;
case CSW_ELITE, CSW_GLOCK18, CSW_MP5NAVY, CSW_TMP: iAmmo = 120;
case CSW_AWP: iAmmo = 30;
case CSW_M249: iAmmo = 200;
case CSW_DEAGLE: iAmmo = 35;
default: return;
}
cs_set_user_bpammo(id, iWeapon, iAmmo);
}
// Дроп взят из плагина (винтовка Mosina), автором которого является Chrescoe (кто автор функции дропа - мне неизвестно)
public DropWeapon(id, slot)
{
static iEntity; iEntity = get_pdata_cbase(id, (pDataKey_iPlayerItems + slot), pData_Player);
if(iEntity > 0)
{
static iNext, szWeaponName[32];
do
{
iNext = get_pdata_cbase(iEntity, pDataKey_iNext, 4);
if(get_weaponname(get_pdata_int(iEntity, pDataKey_iId, 4), szWeaponName, 31))
engclient_cmd(id, "drop", szWeaponName)
} while((iEntity = iNext) > 0);
}
}