#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
native is_user_zombie(id)
#define PLUGIN "FOOTSTEPS ZOMBIE"
#define VERSION "1.1"
#define AUTHOR "fl0wer | MayroN"
#define FOOTSTEPS_DELAY 0.5 // Через сколько секунд Рисовать кровавый след Зомби
#define FOOTSTEPS_DELETE 3.0 // Через сколько секунд Удалять кровавый след Зомби
#define MODEL_FOOTSTEPS "models/footsteps_zombie/footsteps_zombie.mdl"
const FOOTSTEPS_OBJECT = 1234
new g_alloced_InfoTarget
new Float:g_nextFootstepsTime[MAX_PLAYERS + 1]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
register_forward(FM_PlayerPreThink, "Footsteps_Zombie", true)
RegisterHam(Ham_TakeDamage, "player", "Fall_Zombie", true);
RegisterHam(Ham_Think, "info_target", "Footsteps_Think_Post", true)
g_alloced_InfoTarget = engfunc(EngFunc_AllocString, "info_target")
}
public plugin_precache()
{
precache_model(MODEL_FOOTSTEPS);
}
public Fall_Zombie(pVictim, eInflictor, pAttacker, Float: flDamage, iDamageBits)
{
if(!is_user_zombie(pVictim))
return HAM_IGNORED;
if(~iDamageBits & DMG_FALL)
return HAM_IGNORED;
new iUserFlags;
iUserFlags = pev(pVictim, pev_flags);
if(!is_user_on_real_ground(pVictim, iUserFlags))
return HAM_IGNORED;
new Float:angles[3], Float:origin[3];
pev(pVictim, pev_origin, origin);
pev(pVictim, pev_angles, angles);
angles[0] = 0.0
Create_Footsteps(origin, angles, 0)
return HAM_IGNORED;
}
public Footsteps_Zombie(id)
{
if(!is_user_alive(id))
return HAM_IGNORED;
if(!is_user_zombie(id))
return HAM_IGNORED;
if(!(pev(id, pev_flags) & FL_ONGROUND))
return HAM_IGNORED;
static Float:time
time = get_gametime()
if(g_nextFootstepsTime[id] > time)
return HAM_IGNORED;
static Float:maxSpeed, Float:velocity[3]
pev(id, pev_maxspeed, maxSpeed)
pev(id, pev_velocity, velocity)
if(maxSpeed <= 1.0 || vector_length(velocity) < maxSpeed - 2.0)
return HAM_IGNORED;
g_nextFootstepsTime[id] = time + FOOTSTEPS_DELAY
static Float:fraction, Float:start[3], Float:end[3], Float:angles[3]
pev(id, pev_origin, start)
pev(id, pev_angles, angles)
angles[0] = 0.0
end = start
end[2] -= 72.0
engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, id, 0)
get_tr2(0, TR_flFraction, fraction)
if (fraction >= 1.0)
return HAM_IGNORED;
get_tr2(0, TR_vecEndPos, end)
Create_Footsteps(end, angles, 1)
return HAM_IGNORED;
}
Create_Footsteps(Float:origin[3], Float:angles[3], body = 0)
{
new footsteps = engfunc(EngFunc_CreateNamedEntity, g_alloced_InfoTarget)
if(!pev_valid(footsteps))
return 0
set_pev(footsteps, pev_body, body);
set_pev(footsteps, pev_angles, angles);
set_pev(footsteps, pev_solid, SOLID_NOT);
set_pev(footsteps, pev_movetype, MOVETYPE_NONE);
set_pev(footsteps, pev_impulse, FOOTSTEPS_OBJECT);
set_pev(footsteps, pev_nextthink, get_gametime() + FOOTSTEPS_DELETE);
set_pev(footsteps, pev_rendermode, kRenderTransAlpha);
set_pev(footsteps, pev_renderamt, 255.0);
engfunc(EngFunc_SetModel, footsteps, MODEL_FOOTSTEPS);
engfunc(EngFunc_SetOrigin, footsteps, origin);
drop_to_floor(footsteps);
LieFlat(footsteps);
return footsteps;
}
public Footsteps_Think_Post(footsteps)
{
if(pev(footsteps, pev_impulse) != FOOTSTEPS_OBJECT)
return
new Float:renderAmount
pev(footsteps, pev_renderamt, renderAmount)
if(renderAmount <= 0.0)
{
set_pev(footsteps, pev_flags, FL_KILLME)
return
}
set_pev(footsteps, pev_nextthink, get_gametime() + 0.1)
set_pev(footsteps, pev_renderamt, floatmax(0.0, renderAmount - 5.0))
}
LieFlat(ent)
{
static Float:origin[3], Float:traceto[3], trace = 0, Float:fraction
pev(ent, pev_origin, origin);
xs_vec_sub(origin, Float:{0.0, 0.0, 10.0}, traceto)
engfunc(EngFunc_TraceLine, origin, traceto, IGNORE_MONSTERS|IGNORE_MISSILE, ent, trace)
get_tr2(trace, TR_flFraction, fraction)
if(fraction == 1.0)
return;
static Float:original_forward[3], Float:angles[3], Float:angles2[3]
pev(ent, pev_angles, angles)
angle_vector(angles, ANGLEVECTOR_FORWARD, original_forward)
static Float:right[3], Float:up[3], Float:fwd[3]
get_tr2(trace, TR_vecPlaneNormal, up)
xs_vec_cross(original_forward, up, right)
xs_vec_cross(up, right, fwd)
vector_to_angle(fwd, angles)
vector_to_angle(right, angles2)
angles[2] = -1.0 * angles2[0]
set_pev(ent, pev_angles, angles)
}
bool:is_user_on_real_ground(pPlayer, iUserFlags)
{
if(~iUserFlags & FL_ONGROUND)
return false;
new pHit;
pHit = pev(pPlayer, pev_groundentity);
if(is_user_connected(pHit))
return false;
else if(!pev_valid(pHit))
return true;
return true;
}