I'm new to scripting,but I want to learn how to do it.I looked at several scripts and thing just get clearer and clearer,but one thing I can't understand.I downloaded Nirhis demo from File Front and Just loved the enemy AI,so I decided to copy it into my game to see how it's working.Everything worked fine,except for one - the enemy didn't attack the player.I mean it bleeds,it dies,it gets alerted,but doesn't attack the player.I Really want to know why is that!!!
Code: Select all
{
HEALTH [40]
HEALTHATTRIBUTE [enemy_health]
DAMAGEATTRIBUTE [health]
TARGET [Player]
YAWSPEED [360]
CAMPYAW [80]
MOVESPEED [150]
STRAFESPEED [80]
CRAWLSPEED [80]
WALKSPEED [90]
IDLEWALKSPEED [50]
WEAPON [pawn_hawker]
PROJECTILE [10mm_shell]
ACCURACY [90]
YOFFSET [20]
CLIPSIZE [16]
SIGHTRANGE [1200]
ALERTSIGHTRANGE [2500]
FOV [120]
ALERTFOV [220]
ATTACKFOV [160]
SPOTDELAY [1.4]
POINTDISTANCE [60]
SEARCHTIME [30]
CAMPSPOTRANGE [300]
CHARGEPERCENTAGE [50]
FIREDELAYMAX [60]
FIREDELAYMIN [20]
FIREMULTIPLIER [0.001]
ATTACKDELAY_ATTACK [0.0]
LOSTSHOOTTIME [3]
SHOOTSOUND [weapon_pistol.wav]
MUZZLEFLASH [Muzzle_pawn_pistol]
ALERTTIME [1]
MELEEDAMAGE [20]
MELEEATTACK [pistol_melee]
MELEERANGE [100]
MELEEDELAY [0.66]
MELEESOUND [fisthit.wav]
LOOTWEAPON [pawn_hawker]
LOOTAMMO [ball]
LOOTAMMOMIN [5]
LOOTAMMOMAX [10]
LOOTRANGE [80]
LOOTSOUND [pickup.wav]
IDLE [pistol_idle]
WALK [pistol_walk]
IDLE_ALERT [pistol_alert_idle]
WALK_ALERT [pistol_alert_walk]
IDLE_ALERT [pistol_attack_idle]
IDLE_ATTACK [pistol_attack_idle]
CROUCH_IDLE [pistol_attack_idlec]
RUN_ATTACK [pistol_attack_run]
WALK_ATTACK [pistol_attack_walk]
CRAWL_ATTACK [pistol_crawl]
STRAFER [pistol_attack_strafer]
STRAFEL [pistol_attack_strafel]
SHOOT_ALERT [pistol_attack_idle]
SHOOT_ATTACK [pistol_attack_shoot]
CROUCH_SHOOT [pistol_attack_shootc]
RELOAD [pistol_reload]
TAKECOVER [pistol_crawl]
CROUCHIDLE [pistol_attack_idlec]
STANDUP [pistol_attack_standup]
CROUCH [pistol_attack_crouch]
HURT [pistol_hurt]
DIE_HEADSHOT [die_headshot]
DIE1 [die1]
DIE2 [die2]
DIE3 [die3]
DIE4 [die4]
alerttimer [0]
firetimer [0]
attacktimer [0]
strafetimer [0]
spottimer [0]
spotted [0]
lasthp [0]
lastdamage [0]
headshot [false]
crouching [false]
nextorder [idle]
nextanimation [pistol_attack_idle]
accuracy [0]
selfangle [0]
idlealangle [0]
deltaangle [0]
chargedirection [0]
chargetimer [0]
findtimer [0]
losttimer [0]
lostcamptimer [0]
searchtimer [0]
losttarget [false]
rotatetimer [0]
strafeamount [0]
fireplus [0]
bullets [0]
nearestwall [10000]
nearestwalldir [0]
furthestwall [0]
furthestwalldir [0]
tmp [0]
walldist [0]
wallangle [0]
avoided [0]
savetimer [-1]
savehealth [none]
savex [none]
savey [none]
savez [none]
savestate [none]
saveyaw [0]
STATE [0]
state [0]
Spawn[ ()
{
Console(true);
AddAttribute(HEALTHATTRIBUTE,-1000,HEALTH);
SetAttribute(HEALTHATTRIBUTE,HEALTH);
AddAttribute("alertdamage",-1000,1000);
SetAttribute("alertdamage",1000);
AddAttribute("playersound",-1000,1000);
SetAttribute("playersound",1000);
SetWeapon(WEAPON);
savehealth = Concat(self.EntityName,"_health");
savestate = Concat(self.EntityName,"_state");
savex = Concat(self.EntityName,"_x");
savey = Concat(self.EntityName,"_y");
savez = Concat(self.EntityName,"_z");
saveyaw = Concat(self.EntityName,"_yaw");
LowLevel("setup");
} ]
setup[ ()
{
self.ThinkTime = 0.1;
SetTarget("TARGET");
SetFOV(FOV);
lasthp = HEALTH + 0;
accuracy = ACCURACY + 0;
bullets = CLIPSIZE + 0;
self.yaw_speed = CAMPYAW;
state = GetAttribute(StringCopy(savestate),"Player");
if(state = 0)
{
AddAttribute(StringCopy(savehealth),-1000,1000,"Player");
AddAttribute(StringCopy(savestate),-1000,1000,"Player");
AddAttribute(StringCopy(savex),-100000,100000,"Player");
AddAttribute(StringCopy(savey),-100000,100000,"Player");
AddAttribute(StringCopy(savez),-100000,100000,"Player");
AddAttribute(StringCopy(saveyaw),-100000,100000,"Player");
self.think = "idle";
return 0;
}
else
{
self.think = "load_state";
return 0;
}
} ]
idle[ ()
{
self.ThinkTime = 0.1;
save_state(1);
if(check_damage() or check_alert())
{
SetFOV(ALERTFOV);
self.yaw_speed = YAWSPEED;
self.think = "alert";
return 0;
}
if(check_playersound())
{
SetFOV(ALERTFOV);
self.yaw_speed = YAWSPEED;
UpdateEnemyVis();
self.ideal_yaw = self.enemy_yaw;
rotatetimer = self.time + 2;
self.think = "alert";
return 0;
}
if(self.animate_at_end)
{
AnimateHold(IDLE);
}
if((self.enemy_range < SIGHTRANGE) and self.enemy_vis and (spotted = 0))
{
spotted = 1;
spottimer = self.time + SPOTDELAY;
}
if((spotted = 1) and (spottimer < self.time))
{
AnimateHold(IDLE_ALERT);
self.think = "enemy_spotted";
}
if(((self.enemy_range > SIGHTRANGE) or (self.enemy_vis = false)) and (spotted = 1))
{
spotted = 0;
}
if(rotatetimer < self.time)
{
tmp = random(0,1000);
if(tmp < 200)
{
tmp = random(0,314);
self.ideal_yaw = tmp/100;
}
else
{
if(tmp < 600)
{
getfurthestwall();
self.ideal_yaw = self.current_yaw + furthestwalldir*0.3490658504;
}
else
{
getnearestwall();
self.ideal_yaw = self.current_yaw + nearestwalldir*0.3490658504 + 3.14;
}
}
rotatetimer = self.time + random(3,6);
}
if(random(0,1000) < 25)
{
AnimateHold(WALK);
self.yawspeed = YAWSPEED;
self.think = "idle_walk";
return 0;
}
ChangeYaw();
debug(self.enemy_vis);
} ]
idle_walk[ ()
{
self.ThinkTime = 0.05;
save_state(1);
if(check_damage() or check_alert())
{
SetFOV(ALERTFOV);
self.yaw_speed = YAWSPEED;
self.think = "alert";
return 0;
}
if(check_playersound())
{
SetFOV(ALERTFOV);
self.yaw_speed = YAWSPEED;
UpdateEnemyVis();
self.ideal_yaw = self.enemy_yaw;
rotatetimer = self.time + 2;
self.think = "alert";
return 0;
}
if(self.animate_at_end)
{
AnimateHold(WALK);
}
if((self.enemy_range < SIGHTRANGE) and self.enemy_vis and (spotted = 0))
{
spotted = 1;
spottimer = self.time + SPOTDELAY;
}
if((spotted = 1) and (spottimer < self.time))
{
AnimateHold(IDLE_ALERT);
self.think = "enemy_spotted";
}
if(((self.enemy_range > SIGHTRANGE) or (self.enemy_vis = false)) and (spotted = 1))
{
spotted = 0;
}
if(walkmove(self.current_yaw,IDLEWALKSPEED) = false)
{
getnearestwall();
Animate(IDLE);
if(nearestwalldir > 8)
{
self.ideal_yaw = self.ideal_yaw + 0.01;
}
else
{
self.ideal_yaw = self.ideal_yaw + 0.01;
}
}
if(rotatetimer < self.time)
{
rotatetimer = self.time + 0.1;
if(random(0,1000) < 100)
{
self.yaw_speed = CAMPYAW;
AnimateHold(IDLE);
self.think = "idle";
return 0;
}
}
ChangeYaw();
debug(self.enemy_vis);
} ]
alert[ ()
{
self.ThinkTime = 0.1;
save_state(2);
check_damage();
DamageAtBone(1000,500,"alertdamage","root");
if(self.animate_at_end)
{
AnimateHold(IDLE_ALERT);
}
if((self.enemy_range < ALERTSIGHTRANGE) and self.enemy_vis)
{
AnimateHold(IDLE_ALERT);
self.think = "enemy_spotted";
}
if(rotatetimer < self.time)
{
tmp = random(0,1000);
if(tmp < 500)
{
tmp = random(0,314);
self.ideal_yaw = tmp/100;
}
else
{
if(tmp < 750)
{
getfurthestwall();
self.ideal_yaw = self.current_yaw + furthestwalldir*0.3490658504;
}
else
{
getnearestwall();
self.ideal_yaw = self.current_yaw + nearestwalldir*0.3490658504 + 3.14;
}
}
rotatetimer = self.time + random(1,2);
}
if(random(0,1000) < 25)
{
AnimateHold(WALK_ALERT);
self.think = "alert_walk";
return 0;
}
ChangeYaw();
debug(self.enemy_vis);
} ]
alert_walk[ ()
{
self.ThinkTime = 0.05;
save_state(2);
check_damage();
if(self.animate_at_end)
{
AnimateHold(WALK_ALERT);
}
if((self.enemy_range < ALERTSIGHTRANGE) and self.enemy_vis)
{
AnimateHold(IDLE_ALERT);
self.think = "enemy_spotted";
}
if(walkmove(self.current_yaw,IDLEWALKSPEED) = false)
{
getnearestwall();
Animate(IDLE_ALERT);
if(nearestwalldir > 8)
{
self.ideal_yaw = self.ideal_yaw + 0.01;
}
else
{
self.ideal_yaw = self.ideal_yaw + 0.01;
}
}
if(rotatetimer < self.time)
{
rotatetimer = self.time + 0.1;
DamageAtBone(1000,500,"alertdamage","root");
if(random(0,1000) < 300)
{
AnimateHold(IDLE_ALERT);
self.think = "alert";
return 0;
}
}
ChangeYaw();
debug(self.enemy_vis);
} ]
enemy_spotted[ ()
{
self.ThinkTime = 0;
check_damage();
UpdateEnemyVis();
losttarget = false;
self.yaw_speed = YAWSPEED;
if(random(0,1000) < CHARGEPERCENTAGE*10)
{
SetFOV(ATTACKFOV);
self.think = "charge";
}
else
{
SetFOV(360);
if(NearestPoint(0,CAMPSPOTRANGE))
{
SetFOV(ATTACKFOV);
findtimer = self.time + 10;
if(crouching)
{
AnimateHold(TAKECOVER);
self.think = "find_cover";
}
else
{
AnimateHold(CROUCH);
nextorder = StringCopy("find_cover");
nextanimation = StringCopy(TAKECOVER);
crouching = true;
self.think = "playanim";
}
}
else
{
SetFOV(ATTACKFOV);
if(crouching)
{
AnimateHold(CROUCH_IDLE);
self.think = "no_cover_crouch";
}
else
{
AnimateHold(IDLE_ATTACK);
self.think = "no_cover_stand";
}
}
}
} ]
find_cover[ ()
{
self.ThinkTime = 0.05;
save_state(3);
check_damage();
self.ideal_yaw = GetYawToPoint();
ChangeYaw();
if(self.enemy_vis)
{
UpdateEnemyVis();
}
if(self.animate_at_end)
{
AnimateHold(TAKECOVER);
}
if(walkmove(self.current_yaw,CRAWLSPEED) = false)
{
avoid();
avoided = avoided + 1;
}
else
{
avoided = 0;
}
if(avoided > 100)
{
AnimateHold(CROUCH_IDLE);
self.think = "no_cover_crouch";
return 0;
}
if(FastPointCheck(POINTDISTANCE))
{
AnimateHold(CROUCH_IDLE);
UpdateEnemyVis();
losttarget = false;
self.think = "in_cover_crouch";
return 0;
}
if(findtimer < self.time)
{
self.think = "no_cover_crouch";
return 0;
}
} ]
in_cover_crouch[ ()
{
self.ThinkTime = 0.1;
save_state(3);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(CROUCH_IDLE);
}
if((self.enemy_vis = false) and (losttarget = false))
{
losttimer = self.time + LOSTSHOOTTIME;
losttarget = true;
}
if((losttimer < self.time) and losttarget)
{
self.think = "lost_target";
return 0;
}
if(bullets < 1)
{
AnimateHold(RELOAD);
nextorder = StringCopy("no_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "reload";
return 0;
}
if((firetimer < self.time) and (GetCollideDistance("shootbone",0,0,100000) > 50) and facing_ideal() and (bullets > 0))
{
AnimateHold(CROUCH_SHOOT);
attacktimer = self.time + ATTACKDELAY_ATTACK;
fireplus = random(FIREDELAYMIN,FIREDELAYMAX);
firetimer = self.time + fireplus/100 + self.enemy_range*FIREMULTIPLIER;
nextorder = StringCopy("in_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "shoot";
}
if(((random(0,1000) < 50) and (GetCollideDistance("shootbone",0,0,100000) < 50)) or (self.enemy_range < MELEERANGE))
{
AnimateHold(STANDUP);
nextorder = StringCopy("in_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
crouching = false;
self.think = "playanim";
}
} ]
in_cover_stand[ ()
{
self.ThinkTime = 0.1;
save_state(3);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(IDLE_ATTACK);
}
if((self.enemy_vis = false) and (losttarget = false))
{
losttimer = self.time + LOSTSHOOTTIME;
losttarget = true;
}
if((losttimer < self.time) and losttarget)
{
self.think = "lost_target";
return 0;
}
if((self.enemy_range < MELEERANGE) and facing_ideal())
{
AnimateHold(MELEEATTACK);
attacktimer = self.time + MELEEDELAY;
nextorder = StringCopy("in_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
self.think = "melee";
return 0;
}
if((firetimer < self.time) and (GetCollideDistance("shootbone",0,0,100000) > 50) and facing_ideal() and (bullets > 0))
{
AnimateHold(SHOOT_ATTACK);
attacktimer = self.time + ATTACKDELAY_ATTACK;
fireplus = random(FIREDELAYMIN,FIREDELAYMAX);
firetimer = self.time + fireplus/100 + self.enemy_range*FIREMULTIPLIER;
nextorder = StringCopy("in_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
self.think = "shoot";
return 0;
}
if((random(0,1000) < 10) or (bullets < 1))
{
AnimateHold(CROUCH);
nextorder = StringCopy("in_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
crouching = true;
self.think = "playanim";
return 0;
}
} ]
no_cover_stand[ ()
{
self.ThinkTime = 0.1;
save_state(3);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(IDLE_ATTACK);
}
if((self.enemy_vis = false) and (losttarget = false))
{
losttimer = self.time + LOSTSHOOTTIME;
losttarget = true;
}
if((losttimer < self.time) and losttarget)
{
self.think = "lost_target";
return 0;
}
if((self.enemy_range < MELEERANGE) and facing_ideal())
{
AnimateHold(MELEEATTACK);
attacktimer = self.time + MELEEDELAY;
nextorder = StringCopy("no_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
self.think = "melee";
return 0;
}
if((firetimer < self.time) and (GetCollideDistance("shootbone",0,0,100000) > 50) and facing_ideal() and (bullets > 0))
{
AnimateHold(SHOOT_ATTACK);
attacktimer = self.time + ATTACKDELAY_ATTACK;
fireplus = random(FIREDELAYMIN,FIREDELAYMAX);
firetimer = self.time + fireplus/100 + self.enemy_range*FIREMULTIPLIER;
nextorder = StringCopy("no_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
self.think = "shoot";
return 0;
}
if((random(0,1000) < 100) or (bullets < 1))
{
AnimateHold(CROUCH);
nextorder = StringCopy("no_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
crouching = true;
self.think = "playanim";
return 0;
}
if(random(0,1000) < 100)
{
AnimateHold(STRAFEL);
strafeamount = random(-1,2);
nextorder = StringCopy("no_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
self.think = "strafe_l";
return 0;
}
if(random(0,1000) < 100)
{
AnimateHold(STRAFER);
strafeamount = random(-1,2);
nextorder = StringCopy("no_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
self.think = "strafe_r";
return 0;
}
} ]
no_cover_crouch[ ()
{
self.ThinkTime = 0.1;
save_state(3);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(CROUCH_IDLE);
}
if((self.enemy_vis = false) and (losttarget = false))
{
losttimer = self.time + LOSTSHOOTTIME;
losttarget = true;
}
if((losttimer < self.time) and losttarget)
{
self.think = "lost_target";
return 0;
}
if(bullets < 1)
{
AnimateHold(RELOAD);
nextorder = StringCopy("no_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "reload";
return 0;
}
if((firetimer < self.time) and (GetCollideDistance("shootbone",0,0,100000) > 50) and facing_ideal() and (bullets > 0))
{
AnimateHold(CROUCH_SHOOT);
attacktimer = self.time + ATTACKDELAY_ATTACK;
fireplus = random(FIREDELAYMIN,FIREDELAYMAX);
firetimer = self.time + fireplus/100 + self.enemy_range*FIREMULTIPLIER;
nextorder = StringCopy("no_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "shoot";
}
if(((random(0,1000) < 50) and (GetCollideDistance("shootbone",0,0,100000) < 50)) or (self.enemy_range < MELEERANGE) or (random(0,1000) < 50))
{
AnimateHold(STANDUP);
nextorder = StringCopy("no_cover_stand");
nextanimation = StringCopy(IDLE_ATTACK);
crouching = false;
self.think = "playanim";
}
} ]
charge[ ()
{
self.ThinkTime = 0.1;
save_state(3);
check_damage();
AnimateHold(RUN_ATTACK);
chargedirection = random(-785,785);
chargetimer = self.time + random(5,20);
self.think = "charge_run";
} ]
charge_run[ ()
{
self.ThinkTime = 0.05;
save_state(3);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(RUN_ATTACK);
}
if((self.enemy_vis = false) and (losttarget = false))
{
losttimer = self.time + LOSTSHOOTTIME;
losttarget = true;
}
if((losttimer < self.time) and losttarget)
{
self.think = "lost_target";
return 0;
}
if((self.enemy_range < MELEERANGE) and facing_ideal())
{
AnimateHold(MELEEATTACK);
attacktimer = self.time + MELEEDELAY;
nextorder = StringCopy("charge");
nextanimation = StringCopy(RUN_ATTACK);
self.think = "melee";
return 0;
}
if(bullets < 1)
{
AnimateHold(RELOAD);
nextorder = StringCopy("charge_run");
nextanimation = StringCopy(RUN_ATTACK);
self.think = "reload";
return 0;
}
if((firetimer < self.time) and (GetCollideDistance("shootbone",0,0,100000) > 50) and facing_ideal() and (bullets > 0))
{
fireplus = random(FIREDELAYMIN,FIREDELAYMAX);
firetimer = self.time + fireplus/100 + self.enemy_range*FIREMULTIPLIER;
fire();
}
if(strafetimer < self.time)
{
if(random(0,1000) < 100)
{
AnimateHold(STRAFEL);
strafeamount = random(-1,1);
nextorder = StringCopy("charge_run");
nextanimation = StringCopy(RUN_ATTACK);
self.think = "strafe_l";
return 0;
}
if(random(0,1000) < 100)
{
AnimateHold(STRAFER);
strafeamount = random(-1,1);
nextorder = StringCopy("charge_run");
nextanimation = StringCopy(RUN_ATTACK);
self.think = "strafe_r";
return 0;
}
if((random(0,1000) < 100) or (bullets < 1))
{
AnimateHold(CROUCH);
nextorder = StringCopy("charge_crawl");
nextanimation = StringCopy(CRAWL_ATTACK);
crouching = true;
self.think = "playanim";
return 0;
}
strafetimer = self.time + 0.5;
}
if(chargetimer < self.time)
{
chargedirection = random(-785,785);
chargetimer = self.time + random(5,20);
}
if(walkmove(self.current_yaw + chargedirection/1000,MOVESPEED) = false)
{
avoid();
avoided = avoided + 1;
}
else
{
avoided = 0;
}
if(avoided > 100)
{
AnimateHold(IDLE_ATTACK);
self.think = "no_cover_stand";
return 0;
}
} ]
charge_crawl[ ()
{
self.ThinkTime = 0.05;
save_state(3);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(CROUCH_IDLE);
}
if((self.enemy_vis = false) and (losttarget = false))
{
losttimer = self.time + LOSTSHOOTTIME;
losttarget = true;
}
if((losttimer < self.time) and losttarget)
{
self.think = "lost_target";
return 0;
}
if(bullets < 1)
{
AnimateHold(RELOAD);
nextorder = StringCopy("no_cover_crouch");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "reload";
return 0;
}
if((firetimer < self.time) and (GetCollideDistance("shootbone",0,0,100000) > 50) and facing_ideal() and (bullets > 0))
{
AnimateHold(CROUCH_SHOOT);
attacktimer = self.time + ATTACKDELAY_ATTACK;
fireplus = random(FIREDELAYMIN,FIREDELAYMAX);
firetimer = self.time + fireplus/100 + self.enemy_range*FIREMULTIPLIER;
nextorder = StringCopy("charge_crawl");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "shoot";
}
if(chargetimer < self.time)
{
chargedirection = random(-785,785);
chargetimer = self.time + random(5,20);
}
if(strafetimer < self.time)
{
if(((random(0,1000) < 250) and (GetCollideDistance("shootbone",0,0,100000) < 50)) or (self.enemy_range < MELEERANGE) or (random(0,1000) < 250))
{
AnimateHold(STANDUP);
nextorder = StringCopy("charge_run");
nextanimation = StringCopy(RUN_ATTACK);
crouching = false;
self.think = "playanim";
}
strafetimer = self.time + 0.5;
}
} ]
lost_target[ ()
{
self.ThinkTime = 0.1;
save_state(4);
check_damage();
if(bullets < CLIPSIZE)
{
if(crouching)
{
AnimateHold(RELOAD);
nextorder = StringCopy("lost_target");
nextanimation = StringCopy(CROUCH_IDLE);
self.think = "reload";
return 0;
}
else
{
AnimateHold(CROUCH);
nextorder = StringCopy("lost_target");
nextanimation = StringCopy(CROUCH_IDLE);
crouching = true;
self.think = "playanim";
return 0;
}
}
searchtimer = self.time + SEARCHTIME;
if(random(-100,100) < 0)
{
if(crouching)
{
AnimateHold(STANDUP);
nextorder = StringCopy("lost_search");
nextanimation = StringCopy(WALK_ATTACK);
crouching = false;
self.think = "playanim";
return 0;
}
else
{
AnimateHold(WALK_ATTACK);
self.think = "lost_search";
return 0;
}
}
else
{
self.yaw_speed = CAMPYAW;
if(crouching)
{
AnimateHold(CROUCH_IDLE);
crouching = true;
self.think = "lost_camp";
return 0;
}
else
{
AnimateHold(CROUCH);
nextorder = StringCopy("lost_camp");
nextanimation = StringCopy(CROUCH_IDLE);
crouching = true;
self.think = "playanim";
return 0;
}
}
} ]
lost_camp[ ()
{
self.ThinkTime = 0.1;
save_state(4);
check_damage();
if(self.animate_at_end)
{
AnimateHold(CROUCH_IDLE);
}
if(self.enemy_vis)
{
UpdateEnemyVis();
self.yaw_speed = YAWSPEED;
self.think = "enemy_spotted";
return 0;
}
if(lostcamptimer < self.time)
{
tmp = random(0,1000);
if(tmp < 400)
{
self.ideal_yaw = self.enemy_yaw;
}
else
{
if(tmp < 800)
{
getfurthestwall();
self.ideal_yaw = self.current_yaw + furthestwalldir*0.3490658504;
}
else
{
getnearestwall();
self.ideal_yaw = self.current_yaw + nearestwalldir*0.3490658504 + 3.14;
}
}
lostcamptimer = self.time + random(3,6);
}
if(searchtimer < self.time)
{
self.yaw_speed = YAWSPEED;
AnimateHold(IDLE_ALERT);
self.think = "alert";
return 0;
}
ChangeYaw();
} ]
lost_search[ ()
{
self.ThinkTime = 0.05;
save_state(4);
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(WALK_ATTACK);
}
if(self.enemy_vis)
{
UpdateEnemyVis();
self.yaw_speed = YAWSPEED;
self.think = "enemy_spotted";
return 0;
}
if((avoided > 100) or (self.enemy_range < POINTDISTANCE))
{
AnimateHold(IDLE_ALERT);
self.think = "alert";
return 0;
}
if(walkmove(self.current_yaw,WALKSPEED) = false)
{
avoid();
avoided = avoided + 1;
}
else
{
avoided = 0;
}
if(searchtimer < self.time)
{
AnimateHold(IDLE_ALERT);
self.think = "alert";
return 0;
}
} ]
shoot[ ()
{
self.ThinkTime = 0.05;
check_damage();
if(self.enemy_vis)
{
UpdateEnemyVis();
losttarget = false;
}
if(self.animate_at_end or (firetimer < self.time))
{
AnimateHold(nextanimation);
self.think = nextorder;
}
if(attacktimer < self.time)
{
fire();
attacktimer = self.time + 10000;
}
} ]
melee[ ()
{
self.ThinkTime = 0.05;
check_damage();
UpdateEnemyVis();
losttarget = false;
if(self.animate_at_end)
{
AnimateHold(nextanimation);
self.think = nextorder;
}
if(attacktimer < self.time)
{
if(facing_ideal())
{
UpdateEnemyVis();
UpdateTarget();
SetEventState("meleedamage",true);
PlaySound(MELEESOUND);
DamageEntity(MELEEDAMAGE,DAMAGEATTRIBUTE,self.target_name);
attacktimer = self.time + 10000;
}
}
} ]
playanim[ ()
{
check_damage();
face();
if(self.animate_at_end)
{
AnimateHold(nextanimation);
self.think = nextorder;
}
} ]
reload[ ()
{
check_damage();
face();
if(self.animate_at_end)
{
bullets = CLIPSIZE + 0;
AnimateHold(nextanimation);
self.think = nextorder;
}
} ]
strafe_l[ ()
{
self.ThinkTime = 0.05;
save_state(3);
check_damage();
face();
if(walkmove(self.current_yaw + 1.570796327,STRAFESPEED) = false)
{
AnimateHold(nextanimation);
self.think = nextorder;
}
if(self.animate_at_end)
{
if(strafeamount < 0)
{
AnimateHold(nextanimation);
self.think = nextorder;
}
else
{
strafeamount = strafeamount - 1;
AnimateHold(STRAFEL);
}
}
} ]
strafe_r[ ()
{
self.ThinkTime = 0.05;
save_state(3);
check_damage();
face();
if(walkmove(self.current_yaw-1.570796327,STRAFESPEED) = false)
{
AnimateHold(nextanimation);
self.think = nextorder;
}
if(self.animate_at_end)
{
if(strafeamount < 0)
{
AnimateHold(nextanimation);
self.think = nextorder;
}
else
{
strafeamount = strafeamount - 1;
AnimateHold(STRAFER);
}
}
} ]
face[ ()
{
debug(self.enemy_vis);
if(self.enemy_vis or check_playersound())
{
UpdateEnemyVis();
losttarget = false;
}
self.ideal_yaw = self.enemy_yaw;
ChangeYaw();
} ]
facing_ideal[ ()
{
selfangle = self.current_yaw/0.0174532925199433;
idealangle = self.enemy_yaw/0.0174532925199433;
deltaangle = selfangle - idealangle;
if (deltaangle > -20 and deltaangle < 20)
{
return true;
}
return false;
} ]
fire[ ()
{
accuracy = ACCURACY + 0;
if(crouching)
{
accuracy = accuracy / 2;
}
if(GetEventState("move"))
{
accuracy = accuracy * 1.25;
}
debug(fireplus);
SetTargetPoint(random(-accuracy,accuracy),1000*sin(-self.enemy_pitch) + random(-accuracy,accuracy) + YOFFSET,1000*cos(self.enemy_pitch) + random(-accuracy,accuracy));
FireProjectile(PROJECTILE,"shootbone",0,0,0,DAMAGEATTRIBUTE);
PlaySound(SHOOTSOUND);
AddExplosion(MUZZLEFLASH,"shootbone",0,0,0);
bullets = bullets - 1;
} ]
check_damage[ ()
{
if(GetAttribute(HEALTHATTRIBUTE) < lasthp)
{
lastdamage = lasthp - GetAttribute(HEALTHATTRIBUTE);
if(LeftCopy(GetLastBoneHit(),4) = "head")
{
ModifyAttribute(HEALTHATTRIBUTE,-2*lastdamage);
AddExplosion("headshot",GetLastBoneHit(),0,0,0);
splatter();
headshot = true;
}
else
{
if(random(0,100) < 25)
{
splatter();
}
headshot = false;
}
if(LeftCopy(GetLastBoneHit(),3) = "arm")
{
ModifyAttribute(HEALTHATTRIBUTE,lastdamage/2);
}
if(LeftCopy(GetLastBoneHit(),4) = "feet")
{
ModifyAttribute(HEALTHATTRIBUTE,lastdamage/2);
}
AddExplosion("bullethit",GetLastBoneHit(),0,0,0);
lasthp = GetAttribute(HEALTHATTRIBUTE);
if(GetAttribute(HEALTHATTRIBUTE) < 0)
{
self.think = "die";
return 0;
}
return true;
}
if(GetAttribute(HEALTHATTRIBUTE) < 0)
{
self.think = "die";
return 0;
}
return false;
} ]
check_alert[ ()
{
if(GetAttribute("alertdamage") < 1000)
{
SetAttribute("alertdamage",1000);
return true;
}
else
{
return false;
}
} ]
check_playersound[ ()
{
if(GetAttribute("playersound") < 1000)
{
SetAttribute("playersound",1000);
return true;
}
else
{
return false;
}
} ]
splatter[ ()
{
SetTargetPoint(1000*cos(self.enemy_yaw) + random(-500,500),random(-500,500),1000*sin(self.enemy_yaw) + random(-500,500));
switch(random(0,3))
{
case 0
{
FireProjectile("bloodbullet1",GetLastBoneHit(),0,0,0,DAMAGEATTRIBUTE);
}
case 1
{
FireProjectile("bloodbullet2",GetLastBoneHit(),0,0,0,DAMAGEATTRIBUTE);
}
case 2
{
FireProjectile("bloodbullet3",GetLastBoneHit(),0,0,0,DAMAGEATTRIBUTE);
}
case 3
{
FireProjectile("bloodbullet1",GetLastBoneHit(),0,0,0,DAMAGEATTRIBUTE);
}
}
} ]
avoid[ ()
{
if((GetCollideDistance("check_feet",0,0,100000) < 40) and (GetCollideDistance("check_upper",0,0,100000) > 60))
{
ForceUp(60);
}
else
{
getnearestwall();
if(nearestwall < 80)
{
if(nearestwalldir > 8)
{
ForceLeft(10);
}
else
{
ForceRight(10);
}
}
}
} ]
getnearestwall[ ()
{
nearestwall = 10000;
nearestwalldir = 0;
for tmp = 0 to 18
{
wallangle = tmp*0.3490658504;
walldist = GetCollideDistance("check_upper",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist < nearestwall)
{
nearestwall = walldist + 0;
nearestwalldir = tmp + 0;
}
walldist = GetCollideDistance("check_lower",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist < nearestwall)
{
nearestwall = walldist + 0;
nearestwalldir = tmp + 0;
}
walldist = GetCollideDistance("check_feet",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist < nearestwall)
{
nearestwall = walldist + 0;
nearestwalldir = tmp + 0;
}
walldist = GetCollideDistance("check_head",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist < nearestwall)
{
nearestwall = walldist + 0;
nearestwalldir = tmp + 0;
}
}
} ]
getfurthestwall[ ()
{
nearestwall = 10000;
nearestwalldir = 0;
for tmp = 0 to 18
{
wallangle = tmp*0.3490658504;
walldist = GetCollideDistance("check_upper",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist > furthestwall)
{
furthestwall = walldist + 0;
furthestwalldir = tmp + 0;
}
walldist = GetCollideDistance("check_lower",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist > furthestwall)
{
furthestwall = walldist + 0;
furthestwalldir = tmp + 0;
}
walldist = GetCollideDistance("check_feet",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist > furthestwall)
{
furthestwall = walldist + 0;
furthestwalldir = tmp + 0;
}
walldist = GetCollideDistance("check_head",10000*sin(wallangle),0,10000*cos(wallangle));
if(walldist > furthestwall)
{
furthestwall = walldist + 0;
furthestwalldir = tmp + 0;
}
}
} ]
save_state[ (STATE)
{
if(savetimer < self.time)
{
SetAttribute(StringCopy(savehealth),GetAttribute(HEALTHATTRIBUTE),"Player");
SetAttribute(StringCopy(savestate),STATE,"Player");
SetAttribute(StringCopy(savex),self.current_X,"Player");
SetAttribute(StringCopy(savey),self.current_Y,"Player");
SetAttribute(StringCopy(savez),self.current_Z,"Player");
SetAttribute(StringCopy(saveyaw),self.current_yaw/0.0174532925199433,"Player");
savetimer = self.time + 1;
}
} ]
load_state[ ()
{
self.ThinkTime = 0.1;
SetAttribute(HEALTHATTRIBUTE,GetAttribute(StringCopy(savehealth),"Player"));
lasthp = GetAttribute(HEALTHATTRIBUTE);
SetPosition(self.EntityName,GetAttribute(StringCopy(savex),"Player"),GetAttribute(StringCopy(savey),"Player"),GetAttribute(StringCopy(savez),"Player"));
self.ideal_yaw = GetAttribute(StringCopy(saveyaw),"Player")*0.0174532925199433;
if(state = 1)
{
AnimateHold(IDLE);
self.think = "idle";
return 0;
}
if(state = 2)
{
SetFOV(ALERTFOV);
self.yaw_speed = YAWSPEED;
self.think = "alert";
return 0;
}
if(state = 3)
{
self.think = "enemy_spotted";
return 0;
}
if(state = 4)
{
self.think = "lost_target";
return 0;
}
if(state = 5)
{
AnimationSpeed(10);
self.think = "die";
headshot = false;
return 0;
}
if(state = 6)
{
HighLevel("Destroy");
return 0;
}
} ]
die[ ()
{
self.ThinkTime = 0.1;
savetimer = -1;
save_state(5);
SetNoCollision();
if(headshot)
{
AnimateHold(DIE_HEADSHOT);
AnimationSpeed(2);
}
else
{
switch(random(0,4))
{
case 0
{
AnimateHold(DIE1);
}
case 1
{
AnimateHold(DIE2);
}
case 2
{
AnimateHold(DIE3);
}
case 3
{
AnimateHold(DIE4);
}
case 4
{
AnimateHold(DIE1);
}
}
}
SetHoldAtEnd(true);
self.think = "death";
} ]
death[ ()
{
self.ThinkTime = 0.1;
if(self.animate_at_end)
{
if(headshot)
{
SetTargetPoint(0,-10000,-10000);
switch(random(0,3))
{
case 0
{
FireProjectile("bloodbullet1","head_head",0,0,0,DAMAGEATTRIBUTE);
}
case 1
{
FireProjectile("bloodbullet2","head_head",0,0,0,DAMAGEATTRIBUTE);
}
case 2
{
FireProjectile("bloodbullet3","head_head",0,0,0,DAMAGEATTRIBUTE);
}
case 3
{
FireProjectile("bloodbullet1","head_head",0,0,0,DAMAGEATTRIBUTE);
}
}
}
self.think = "loot";
}
} ]
loot[ ()
{
self.ThinkTime = 0.4;
if(GetDistanceTo("player") < LOOTRANGE)
{
ModifyAttribute(LOOTWEAPON,1,"Player");
ModifyAttribute(LOOTAMMO,random(LOOTAMMOMIN,LOOTAMMOMAX),"Player");
PlaySound(LOOTSOUND);
savetimer = -1;
save_state(6);
HighLevel("Looted");
}
DamageAtBone(1000,500,"alertdamage","root");
} ]
Looted[ ()
{
RemoveWeapon();
FadeOut(1,0);
NewOrder("Destroy");
} ]
Destroy[ ()
{
Remove(true);
} ]
}