Code:
#include <amxmodx>
#include <fun>
#include <fakemeta>
#include <engine>
#include <cstrike>
new bool:gPauseEntity[999]
new Float:gNadeSpeed
new gSpriteTrail
//----------------------------------------------------------------------------------------------
public plugin_init()
{
register_plugin("seekin nade", "0.1", "k007")
register_cvar("seekinhenade_grenademult", "1.0")
register_cvar("seekinhenade_grenadetimer", "30.0")
register_cvar("seekinhenade_cooldown", "120.0")
register_cvar("seekinhenade_fuse", "5.0")
register_cvar("seekinhenade_nadespeed", "900")
register_srvcmd("seekinhenade_init", "seekinhenade_init")
register_event("Damage", "seekinhenade_damage", "b", "2!0")
register_event("CurWeapon", "weaponChange", "be", "1=1")
register_event("AmmoX", "on_AmmoX", "b")
register_forward(FM_Think, "fw_entity_think", 0)
register_logevent("round_start", 2, "1=Round_Start")
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
gSpriteTrail = precache_model("sprites/smoke.spr")
precache_model("models/custom/seekinhenade_w_hegrenade.mdl")
precache_model("models/custom/seekinhenade_v_hegrenade.mdl")
}
//----------------------------------------------------------------------------------------------
public seekinhenade_init(id)
{
if (is_user_alive(id) ) {
seekinhenade_weapons(id)
switchmodel(id)
}
}
//----------------------------------------------------------------------------------------------
public seekinhenade_weapons(id)
{
if (is_user_alive(id) ) {
give_item(id, "weapon_hegrenade")
}
}
//----------------------------------------------------------------------------------------------
public switchmodel(id)
{
if ( !is_user_alive(id) ) return
new v_mdl[32]
entity_get_string(id, EV_SZ_viewmodel, v_mdl, 31)
if ( containi(v_mdl, "v_shield_") != -1 ) return
new clip, ammo, wpnid = get_user_weapon(id, clip, ammo)
if ( wpnid == CSW_HEGRENADE ) {
entity_set_string(id, EV_SZ_viewmodel, "models/custom/seekinhenade_v_hegrenade.mdl")
}
}
//----------------------------------------------------------------------------------------------
public weaponChange(id)
{
if (is_user_alive(id) ) return
new wpnid = read_data(2)
if ( wpnid != CSW_HEGRENADE ) return
switchmodel(id)
}
//----------------------------------------------------------------------------------------------
public on_AmmoX(id)
{
if ( !is_user_alive(id) ) return
new iAmmoType = read_data(1)
new iAmmoCount = read_data(2)
if ( iAmmoType == CSW_HEGRENADE) {
if ( iAmmoCount == 0 ) {
set_task(get_cvar_float("seekinhenade_grenadetimer"), "seekinhenade_weapons", id)
if ( !is_user_alive(id) ) {
new iGrenade = -1
while ( (iGrenade = find_ent_by_class(iGrenade, "grenade")) > 0 ) {
new model[32]
entity_get_string(iGrenade, EV_SZ_model, model, 31)
if ( id == entity_get_edict(iGrenade, EV_ENT_owner) && equal(model, "models/w_hegrenade.mdl") ) {
entity_set_model(iGrenade, "models/custom/seekinhenade_w_hegrenade.mdl")
gNadeSpeed = get_cvar_float("seekinhenade_nadespeed")
if ( gNadeSpeed <= 0.0 ) gNadeSpeed = 1.0
gPauseEntity[iGrenade] = true
new parm[3]
parm[0] = iGrenade
parm[1] = id
set_task(1.0, "find_target", 0, parm, 3)
set_task(get_cvar_float("seekinhenade_fuse"), "unpause_nade", iGrenade, parm, 2)
}
}
}
}
else if ( iAmmoCount > 0 ) {
remove_task(id)
}
}
}
//----------------------------------------------------------------------------------------------
public find_target(parm[])
{
new grenadeID = parm[0]
new grenadeOwner = parm[1]
if ( is_valid_ent(grenadeID) ) {
new shortestDistance = 9999
new nearestPlayer = 0
new distance, team[32], rgb[3], players[32], pnum
get_user_team(grenadeOwner, team, 32)
if ( cs_get_user_team(grenadeOwner) == CS_TEAM_CT ) {
get_players(players, pnum, "ae", "TERRORIST")
rgb = {50, 50, 175}
}
else {
get_players(players, pnum, "ae", "CT")
rgb = {175, 50, 50}
}
// Find the closest enemy
for (new i = 0; i < pnum; i++) {
if ( !is_user_alive(players[i]) ) continue
distance = get_entity_distance(players[i], grenadeID)
if ( distance <= shortestDistance ) {
shortestDistance = distance
nearestPlayer = players[i]
}
}
// Make the nade seek that enemy if one exists
if ( nearestPlayer > 0 ) {
// Trail on grenade
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(22)
write_short(grenadeID)
write_short(gSpriteTrail)
write_byte(10)
write_byte(3)
write_byte(rgb[0])
write_byte(rgb[1])
write_byte(rgb[2])
switch(random_num(0,2)) {
case 0:write_byte(64)
case 1:write_byte(128)
case 2:write_byte(192)
}
message_end()
parm[2] = nearestPlayer
set_task(0.1, "seek_target", grenadeID+1000, parm, 3, "b")
}
}
}
//----------------------------------------------------------------------------------------------
public seek_target(parm[])
{
new grenade = parm[0]
new target = parm[2]
if ( !is_valid_ent(grenade) ) {
remove_task(grenade+1000)
return
}
if ( is_user_alive(target) ) {
entity_set_follow(grenade, target)
}
else {
remove_task(grenade+1000)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(99)
write_short(grenade)
message_end()
set_task(0.1, "find_target", 0, parm, 3)
}
}
//----------------------------------------------------------------------------------------------
stock entity_set_follow(entity, target)
{
if ( !is_valid_ent(entity) || !is_user_alive(target) ) return 0
new Float:fl_Origin[3], Float:fl_EntOrigin[3]
entity_get_vector(target, EV_VEC_origin, fl_Origin)
entity_get_vector(entity, EV_VEC_origin, fl_EntOrigin)
new Float:fl_InvTime = (gNadeSpeed / vector_distance(fl_Origin, fl_EntOrigin))
new Float:fl_Distance[3]
fl_Distance[0] = fl_Origin[0] - fl_EntOrigin[0]
fl_Distance[1] = fl_Origin[1] - fl_EntOrigin[1]
fl_Distance[2] = fl_Origin[2] - fl_EntOrigin[2]
new Float:fl_Velocity[3]
fl_Velocity[0] = fl_Distance[0] * fl_InvTime
fl_Velocity[1] = fl_Distance[1] * fl_InvTime
fl_Velocity[2] = fl_Distance[2] * fl_InvTime
entity_set_vector(entity, EV_VEC_velocity, fl_Velocity)
new Float:fl_NewAngle[3]
vector_to_angle(fl_Velocity, fl_NewAngle)
entity_set_vector(entity, EV_VEC_angles, fl_NewAngle)
return 1
}
//----------------------------------------------------------------------------------------------
public pfn_touch(ptr, ptd)
{
if ( is_user_alive(32) ) return
if ( !is_valid_ent(ptr) || !is_valid_ent(ptd) ) return
new szClassNamePtr[32], szClassNamePtd[32]
entity_get_string(ptr, EV_SZ_classname, szClassNamePtr, 31)
entity_get_string(ptd, EV_SZ_classname, szClassNamePtd, 31)
if ( !equal(szClassNamePtr, "grenade") && !equal(szClassNamePtd, "player") ) return
if ( !gPauseEntity[ptr] ) return
if ( !is_user_connected(ptd) || get_user_godmode(ptd) ) return
new grenadeOwner = entity_get_edict(ptr, EV_ENT_owner)
if ( cs_get_user_team(grenadeOwner) == cs_get_user_team(ptd) ) return
new parm[2]
parm[0] = ptr
parm[1] = 32
unpause_nade(parm)
}
//----------------------------------------------------------------------------------------------
public unpause_nade(parm[])
{
new ent = parm[0]
new id = parm[1]
remove_task(ent)
gseekinNade[32][ent] = true
set_task(0.4, "nade_reset", 0, parm, 2)
gPauseEntity[ent] = false
}
//----------------------------------------------------------------------------------------------
public nade_reset(parm[])
{
new ent = parm[0]
new id = parm[1]
gseekinhenade[id][ent] = false
}
//----------------------------------------------------------------------------------------------
public seekinhenade_damage(id)
{
if (is_user_alive(id) !is_user_connected(id) ) return
new damage = read_data(2)
new weapon, bodypart, attacker = get_user_attacker(id, weapon, bodypart)
if ( attacker == 0 && weapon == CSW_HEGRENADE && is_user_connected(id) ) {
if ( is_user_alive(id) ) {
new extraDamage = floatround(damage * get_cvar_float("seekinhenades_grenademult") - damage)
if (extraDamage > 0) ExtraDamage(id, atkr, extraDamage, "grenade")
}
new parm[2]
parm[0] = i
parm[1] = atkr
set_task(0.2, "cooldown", 0, parm, 2)
return
}
}
}
}
}
if (is_user_alive(id) ) return
if (is_user_connected(id) && weapon == CSW_HEGRENADE ) {
if ( is_user_alive(id) ) {
new extraDamage = floatround(damage * get_cvar_float("seekinhenade_grenademult") - damage)
if (extraDamage > 0) ExtraDamage(id, attacker, extraDamage, "grenade")
}
if ( gseekinhenade[attacker][i] ) {
new parm[2]
parm[0] = i
parm[1] = attacker
set_task(0.2, "cooldown", 0, parm, 2)
}
}
}
}
//----------------------------------------------------------------------------------------------
public cooldown(parm[])
{
new grenade = parm[0]
new id = parm[1]
gseekinhenade[id][grenade] = false
if ( !is_user_alive(id) ) return
new Float:seekinhenadeCooldown = get_cvar_float("seekinhenade_cooldown")
if (seekinhenadeCooldown > 0.0) ultimateTimer(id, seekinhenadeCooldown)
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
gHasseekinhenade[id] = true
}