PHP Code:
public fw_snowman_thinks(ent)
{
static Float:fOrigin[3], Float:fVelocity[3], iTask, Float:fGtime, iFlags, Float:fDelay=-1.0;
pev(ent, pev_origin, fOrigin);
iTask = pev(ent, PEV_TASK);
fGtime = get_gametime();
iFlags = pev(ent, pev_flags);
pev(ent, pev_velocity, fVelocity);
switch( iTask )
{
case SNOWMAN_IDLE_STATE:
{
fVelocity[0] = fVelocity[1] = 0.0;
set_pev(ent, pev_velocity, fVelocity);
npc_animation(ent, fVelocity, iFlags);
if(random(100) >= 70)
{
set_pev(ent, PEV_TASK, SNOWMAN_ROAMING_STATE);
}
else
{
set_pev(ent, PEV_TASK, SNOWMAN_IDLE_STATE);
}
set_pev(ent, pev_nextthink, fGtime + SNOWMAN_THINK_LEN);
}
case SNOWMAN_ROAMING_STATE:
{
static Float:fEnd[3], Float:fMaxTraceLength, iTr2;
iTr2 = create_tr2();
fMaxTraceLength = 100.0;
pev(ent, pev_angles, fEnd);
angle_vector(fEnd, ANGLEVECTOR_FORWARD, fEnd);
xs_vec_mul_scalar(fEnd, fMaxTraceLength, fEnd);
xs_vec_add(fEnd, fOrigin, fEnd);
engfunc(EngFunc_TraceLine, fOrigin, fEnd, 0, ent, iTr2);
static Float:flFraction;
get_tr2(iTr2, TR_flFraction, flFraction);
if(flFraction < 1.0)
{
pev(ent, pev_angles, fEnd);
fEnd[1] += 45.0;
set_pev(ent, pev_angles, fEnd);
}
else {
MoveToOrigin(ent, fEnd, 250.0, 0.0);
}
free_tr2(iTr2);
set_pev(ent, pev_nextthink, fGtime + SNOWMAN_THINK_LEN);
}
case SNOWMAN_ATTACK_STATE:
{
static iVictim, Float:fHealth; fHealth = 0.0;
if(pev_valid((iVictim = pev(ent, PEV_TARGET))))
pev(iVictim, pev_health, fHealth);
if(pev_valid(iVictim) && fHealth > 0.0)
{
static iHit, Float:fTraceAttack, Float:fOriginDest[3];
pev(iVictim, pev_origin, fOriginDest);
if(get_distance_f(fOrigin, fOriginDest) >= 400.0)
{
set_pev(ent, PEV_TASK, SNOWMAN_IDLE_STATE);
set_pev(ent, PEV_TARGET, 0);
set_pev(ent, pev_nextthink, fGtime + SNOWMAN_THINK_LEN);
return;
}
pev(ent, pev_fuser1, fDelay);
fTraceAttack = 100.0;
LookAtOrigin(ent, fOriginDest);
iHit = npc_traceattack(ent, fOriginDest, fTraceAttack);
if(iHit > 0 && pev_valid(iHit))
{
static Float:fVicSpeed, Float:fVictimVelo[3], Float:fVicOrigin[3], Float:fAttackDelay;
fAttackDelay = 0.6;
pev(iHit, pev_origin, fVicOrigin);
pev(iHit, pev_velocity, fVictimVelo);
fVicSpeed = floatmax(xs_vec_len(fVictimVelo), 1.0);
xs_vec_div_scalar(fVictimVelo, fVicSpeed, fVictimVelo);
xs_vec_mul_scalar(fVictimVelo, (fVicSpeed * fAttackDelay), fVictimVelo);
xs_vec_add(fVictimVelo, fVicOrigin, fVictimVelo);
if(get_distance_f(fOrigin, fVictimVelo) <= fTraceAttack + 10.0)
{
if(fDelay == -1.0)
{
fDelay = fGtime + fAttackDelay;
if(Iattack1 > 0)
{
static xArray[ANIMATION_DATA];
ArrayGetArray(anim_attack1, random(Iattack1), xArray)
static Float:fFrameRate;
fFrameRate = ( xArray[ANIMATION_FRAMES] / xArray[ANIMATION_FPS] ) / fAttackDelay;
PlayAnimation(ent, xArray[ANIMATION_SEQUENCE], fFrameRate, ANIM_ATTACK1);
}
}
else if(fDelay < fGtime)
{
npc_takedamage(ent, iHit, 15.0, DMG_SLASH);
fDelay = -1.0;
}
}
else
{
npc_animation(ent, fVelocity, iFlags);
}
}
else
{
fDelay = -1.0;
MoveToOrigin(ent, fOriginDest, 250.0, 0.0);
// fvelocity needs to be retrieved again since MoveToOrigin effects velocity!
pev(ent, pev_velocity, fVelocity);
npc_animation(ent, fVelocity, iFlags);
}
set_pev(ent, pev_fuser1, fDelay);
}
else
{
set_pev(ent, PEV_TASK, SNOWMAN_IDLE_STATE);
set_pev(ent, PEV_TARGET, 0);
}
set_pev(ent, pev_nextthink, fGtime + SNOWMAN_THINK_LEN);
}
}
if(iTask != SNOWMAN_ATTACK_STATE)
{
pev(ent, pev_fuser1, fDelay);
if(fDelay < fGtime) {
static ent_seek, Float:fHP, Float:fOriginDest[3]; ent_seek = -1;
while((ent_seek=find_ent_in_sphere(ent_seek, fOrigin, 300.0)) > 0)
{
pev(ent_seek, pev_origin, fOriginDest);
if(ent_seek != npc_traceattack(ent, fOriginDest, get_distance_f(fOrigin, fOriginDest)))
continue;
pev(ent_seek, pev_health, fHP);
if(pev(ent_seek, pev_takedamage) != DAMAGE_NO &&
pev(ent_seek, pev_solid) != SOLID_NOT &&
pev(ent_seek, pev_solid) != SOLID_TRIGGER &&
fHP > 0.0 )
{
break;
}
}
if(ent_seek > 0)
{
set_pev(ent, PEV_TARGET, ent_seek);
set_pev(ent, PEV_TASK, SNOWMAN_ATTACK_STATE);
}
set_pev(ent, pev_fuser1, fGtime + 1.0);
}
}
}