Код:
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <fakemeta_util>
#include <hamsandwich>
#include <xs>
#include <hl>
#include <hl_wpnmod>
#define NPC_CLASS "npc_turret"
#define NPC_MODEL "models/turret.mdl"
#define NPC_HP 350
enum
{
NPC_IDLE = 0,
NPC_ATTACK,
NPC_HIT,
NPC_ATTACK_GRENADE,
NPC_DIE,
NPC_TURN
}
new const g_sound_spawn[] = "turret/tu_deploy.WAV"
new const g_sound_fire[] = "turret/tu_fire1.wav"
new const g_sound_die[] = "turret/tu_die3.WAV"
new const anim_dead[] = {5, 5, 5, 5, 5}
new g_blood, g_bloodspray
new Float:angles[3]
new Floatrigin_npc[3], Floatrigin_player[3], Float:distansion
new player_id
new cvar_angles_pitch
new cvar_angles_yaw
new cvar_angles_roll
new Float:y_stupid[3]
public plugin_init()
{
register_plugin("[NPC] Turret", "0.1", "batcon")
RegisterHam(Ham_TakeDamage, "info_target", "npc_TakeDamage")
register_think(NPC_CLASS,"npc_think")
cvar_angles_pitch = register_cvar("npc_angles_pitch", "0")
cvar_angles_yaw = register_cvar("npc_angles_yaw", "0")
cvar_angles_roll = register_cvar("npc_angles_roll", "0")
register_clcmd("turret", "spawn_npc")
register_clcmd("round?", "round_end_kill")
}
public plugin_precache()
{
engfunc(EngFunc_PrecacheModel, NPC_MODEL)
precache_sound(g_sound_spawn)
precache_sound(g_sound_die)
precache_sound(g_sound_fire)
g_blood = precache_model("sprites/blood.spr")
g_bloodspray = precache_model("sprites/bloodspray.spr")
static mapname[64]
get_mapname(mapname, sizeof(mapname))
if(equal(mapname, "horror"))
{
y_stupid[0] = -1020.0
y_stupid[1] = 54.0
y_stupid[2] = 64.0
}
if(equal(mapname, "hlsub5"))
{
y_stupid[0] = 1100.0
y_stupid[1] = 3140.0
y_stupid[2] = 616.0
}
}
public menu(id)
{
new i_Menu = menu_create("\y[Creative NPC]:", "comand_menu")
menu_additem(i_Menu, "\y[Creative NPC]", "1", 0)
menu_additem(i_Menu, "\y[Delete NPC]", "2", 0)
menu_additem(i_Menu, "\y[Delete all NPC]", "3", 0)
menu_setprop(i_Menu, MPROP_EXIT, MEXIT_ALL)
menu_display(id, i_Menu, 0)
return PLUGIN_HANDLED
}
public comand_menu(id, menu, item)
{
if (item == MENU_EXIT)
{
menu_destroy(menu)
return PLUGIN_HANDLED
}
new s_Data[6], s_Name[64], i_Access, i_Callback
menu_item_getinfo(menu, item, i_Access, s_Data, charsmax(s_Data), s_Name, charsmax(s_Name), i_Callback)
new i_Key = str_to_num(s_Data)
switch(i_Key)
{
case 1:
{
spawn_npc(id)
}
case 2:
{
delet_npc(id)
}
case 3:
{
}
}
menu_destroy(menu)
return PLUGIN_HANDLED
}
public spawn_npc(id)
{
new g_npc = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
player_id = id
angles[0] = get_pcvar_float(cvar_angles_pitch)
angles[1] = get_pcvar_float(cvar_angles_yaw)
angles[2] = get_pcvar_float(cvar_angles_roll)
engfunc(EngFunc_SetModel, g_npc, NPC_MODEL)
engfunc(EngFunc_SetSize, g_npc, { -16.0, -16.0, 0.0 }, { 16.0, 16.0, 62.0 })
static Float:Origin[3]
Origin[0] = y_stupid[0]
Origin[1] = y_stupid[1]
Origin[2] = y_stupid[2]
entity_set_origin(g_npc, Origin)
set_pev(g_npc, pev_classname, NPC_CLASS)
set_pev(g_npc, pev_solid, SOLID_SLIDEBOX)
set_pev(g_npc, pev_movetype, MOVETYPE_TOSS)
set_pev(g_npc, pev_takedamage, DAMAGE_AIM)
set_pev(g_npc, pev_health, float(NPC_HP))
set_pev(g_npc, pev_deadflag, DEAD_NO)
set_pev(g_npc, pev_nextthink, get_gametime() + 0.1)
set_pev(g_npc, pev_angles, angles)
set_pev(g_npc, pev_gravity, 35.0)
npc_ability(g_npc, NPC_IDLE, 0)
entity_set_byte(g_npc, EV_BYTE_controller2, 157)
entity_set_byte(g_npc, EV_BYTE_controller3, 157)
entity_set_byte(g_npc, EV_BYTE_controller4, 157)
Util_PlayAnimation(g_npc, 3)
set_pev(g_npc, pev_nextthink, get_gametime() + 0.
emit_sound(g_npc, CHAN_VOICE, g_sound_spawn, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
public npc_TakeDamage(victim, weapon, attacker, Float:damage, damagetype)
{
static classname[32]
pev(victim, pev_classname, classname, charsmax(classname))
if(equal(classname, NPC_CLASS))
{
if(pev(victim, pev_health) <= 100.0)
{
npc_ability(victim, NPC_DIE, attacker)
}
}
return HAM_HANDLED
}
public npc_think(ent)
{
if(!is_valid_ent(ent))
return FMRES_IGNORED
if(pev(ent, pev_iuser4) == 1)
return HAM_IGNORED
distansion = get_distance_f(origin_npc, origin_player)
pev(ent, pev_origin, origin_npc)
pev(player_id, pev_origin, origin_player)
if(distansion < 670.0)
{
npc_ability(ent, NPC_ATTACK, player_id)
}
else
{
npc_ability(ent, NPC_IDLE, 0)
}
return FMRES_HANDLED
}
public npc_ability(ent, ability, index)
{
switch(ability)
{
case NPC_IDLE:
{
Util_PlayAnimation(ent, 2)
set_pev(ent, pev_nextthink, get_gametime() + 0.0)
}
case NPC_DIE:
{
Util_PlayAnimation(ent, anim_dead[random(sizeof anim_dead)])
set_pev(ent, pev_iuser4, 1)
set_pev(ent, pev_solid, SOLID_NOT)
set_pev(ent, pev_takedamage, DAMAGE_NO)
set_task(8.0, "delet", ent)
set_pev(ent, pev_nextthink, get_gametime() + 9999.0)
emit_sound(ent, CHAN_VOICE, g_sound_die, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return HAM_IGNORED
}
case NPC_TURN:
{
Util_PlayAnimation(ent, 0)
set_pev(ent, pev_nextthink, get_gametime() + 3.0)
return FMRES_HANDLED
}
case NPC_ATTACK:
{
Util_PlayAnimation(ent, 1)
set_pev(ent, pev_nextthink, get_gametime() + 0.15)
set_task(0.0, "attackhit", ent)
pev(index, pev_origin, origin_player)
aim_at_origin(ent, origin_player, angles)
angles[0] = 0.0
set_pev(ent, pev_angles, angles)
}
case NPC_HIT:
{
static victim
static Float:Origin[3], Float:VicOrigin[3]
victim = FindClosesEnemy(ent)
pev(ent, pev_origin, Origin)
pev(victim, pev_origin, VicOrigin)
new tName[33]
new g_ifinder
emit_sound(ent, CHAN_BODY, g_sound_fire, 1.0, ATTN_NORM, 0, PITCH_NORM)
pev(ent, pev_targetname, tName, sizeof(tName)-1)
if(equal(tName, "npc_barneyzombie"))
if (ent != g_ifinder && equal(tName, "npc_barneyzombie"))
{
create_tracer(ent, origin_npc, tName)
}
return FMRES_HANDLED
}
}
return HAM_HANDLED
}
public delet_npc(id)
{
new ent, body, classname[32];
get_user_aiming(id, ent, body);
if(is_valid_ent(ent))
{
pev(ent, pev_classname, classname, charsmax(classname))
if(equal(classname, NPC_CLASS))
{
remove_entity(ent)
}
}
}
public delet(ent)
{
remove_entity(ent)
}
public attackhit(ent)
{
npc_ability(ent, NPC_HIT, player_id)
}
public round_end_kill(ent)
{
remove_entity_name(NPC_CLASS)
}
stock create_tracer(ent, Float:start[3], Float:end[3])
{
new start_[3], end_[3]
FVecIVec(start, start_)
FVecIVec(end, end_)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_TRACER)
write_coord(start_[0])
write_coord(start_[1])
write_coord(start_[2])
write_coord(end_[0])
write_coord(end_[1])
write_coord(end_[2])
message_end()
static tr, Float:End_Origin[3], Target
engfunc(EngFunc_TraceLine, start, end, DONT_IGNORE_MONSTERS, -1, tr)
get_tr2(tr, TR_vecEndPos, End_Origin)
Target = get_tr2(tr, TR_pHit)
if(is_user_alive(Target))
{
static Float:Origin[3]
pev(Target, pev_origin, Origin)
// Show some blood
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BLOODSPRITE)
write_coord(floatround(Origin[0]))
write_coord(floatround(Origin[1]))
write_coord(floatround(Origin[2]))
write_short(g_bloodspray)
write_short(g_blood)
write_byte(70)
write_byte(random_num(1,12))
message_end()
ExecuteHamB(Ham_TakeDamage, Target, 0, Target, 4.0, DMG_BULLET)
}
make_bullet(ent, End_Origin)
}
stock make_bullet(ent, Float:TOrigin[3])
{
// Show sparcles
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_GUNSHOTDECAL)
write_coord(floatround(TOrigin[0]))
write_coord(floatround(TOrigin[1]))
write_coord(floatround(TOrigin[2]))
write_short(ent)
write_byte(41)
message_end()
}
stock Util_PlayAnimation(index, sequence, Float: framerate = 1.0)
{
set_pev(index, pev_animtime, get_gametime())
set_pev(index, pev_framerate, framerate)
set_pev(index, pev_frame, 0.0)
set_pev(index, pev_sequence, sequence)
}
stock aim_at_origin(id, Float:target[3], Float:angles[3])
{
static Float:vec[3]
pev(id, pev_origin, vec)
vec[0] = target[0] - vec[0]
vec[1] = target[1] - vec[1]
vec[2] = target[2] - vec[2]
engfunc(EngFunc_VecToAngles, vec, angles)
angles[0] *= -1.0, angles[2] = 0.0
}
public npc_turntotarget(ent, Float:Ent_Origin[3], target, Float:Vic_Origin[3])
{
if(target)
{
new Float:newAngle[3]
entity_get_vector(ent, EV_VEC_angles, newAngle)
new Float = Vic_Origin[0] - Ent_Origin[0]
new Float:z = Vic_Origin[1] - Ent_Origin[1]
new Float:radians = floatatan(z/x, radian)
newAngle[1] = radians * (100 / 3.14)
if (Vic_Origin[0] < Ent_Origin[0])
newAngle[1] -= 100.0
entity_set_vector(ent, EV_VEC_angles, newAngle)
}
}
stock get_position(id,Float:forw, Float:right, Float:up, Float:vStart[])
{
new Float:vOrigin[3], Float:vAngle[3], Float:vForward[3], Float:vRight[3], Float:vUp[3]
pev(id, pev_origin, vOrigin)
pev(id, pev_view_ofs,vUp)
xs_vec_add(vOrigin,vUp,vOrigin)
pev(id, pev_v_angle, vAngle)
vAngle[0] = 0.0
angle_vector(vAngle,ANGLEVECTOR_FORWARD,vForw ard)
angle_vector(vAngle,ANGLEVECTOR_RIGHT,vRight)
angle_vector(vAngle,ANGLEVECTOR_UP,vUp)
vStart[0] = vOrigin[0] + vForward[0] * forw + vRight[0] * right + vUp[0] * up
vStart[1] = vOrigin[1] + vForward[1] * forw + vRight[1] * right + vUp[1] * up
vStart[2] = vOrigin[2] + vForward[2] * forw + vRight[2] * right + vUp[2] * up
}
public FindClosesEnemy(entid)
{
new Floatist
new Float:maxdistance=4000.0
new indexid=0
for(new i=1;i<=get_maxplayers();i++){
if(is_user_alive(i) && is_valid_ent(i) && can_see_fm(entid, i))
{
Dist = entity_range(entid, i)
if(Dist <= maxdistance)
{
maxdistance=Dist
indexid=i
return indexid
}
}
}
return 0
}
public bool:can_see_fm(entindex1, entindex2)
{
if (!entindex1 || !entindex2)
return false
if (pev_valid(entindex1) && pev_valid(entindex1))
{
new flags = pev(entindex1, pev_flags)
if (flags & EF_NODRAW || flags & FL_NOTARGET)
{
return false
}
new Float:lookerOrig[3]
new Float:targetBaseOrig[3]
new Float:targetOrig[3]
new Float:temp[3]
pev(entindex1, pev_origin, lookerOrig)
pev(entindex1, pev_view_ofs, temp)
lookerOrig[0] += temp[0]
lookerOrig[1] += temp[1]
lookerOrig[2] += temp[2]
pev(entindex2, pev_origin, targetBaseOrig)
pev(entindex2, pev_view_ofs, temp)
targetOrig[0] = targetBaseOrig [0] + temp[0]
targetOrig[1] = targetBaseOrig [1] + temp[1]
targetOrig[2] = targetBaseOrig [2] + temp[2]
engfunc(EngFunc_TraceLine, lookerOrig, targetOrig, 0, entindex1, 0) // checks the had of seen player
if (get_tr2(0, TraceResult:TR_InOpen) && get_tr2(0, TraceResult:TR_InWater))
{
return false
}
else
{
new Float:flFraction
get_tr2(0, TraceResult:TR_flFraction, flFraction)
if (flFraction == 1.0 || (get_tr2(0, TraceResult:TR_pHit) == entindex2))
{
return true
}
else
{
targetOrig[0] = targetBaseOrig [0]
targetOrig[1] = targetBaseOrig [1]
targetOrig[2] = targetBaseOrig [2]
engfunc(EngFunc_TraceLine, lookerOrig, targetOrig, 0, entindex1, 0) // checks the body of seen player
get_tr2(0, TraceResult:TR_flFraction, flFraction)
if (flFraction == 1.0 || (get_tr2(0, TraceResult:TR_pHit) == entindex2))
{
return true
}
else
{
targetOrig[0] = targetBaseOrig [0]
targetOrig[1] = targetBaseOrig [1]
targetOrig[2] = targetBaseOrig [2] - 17.0
engfunc(EngFunc_TraceLine, lookerOrig, targetOrig, 0, entindex1, 0) // checks the legs of seen player
get_tr2(0, TraceResult:TR_flFraction, flFraction)
if (flFraction == 1.0 || (get_tr2(0, TraceResult:TR_pHit) == entindex2))
{
return true
}
}
}
}
}
return false
}