Page 1 of 1

I'm Trying To Understand Why Is This Happening.

Posted: Tue Jun 17, 2008 5:15 pm
by metal_head
(just to inform you guys,I'm not gonna use this scipt in my game,because that would be stealing.I just want to encrease my skills in programing by learning from this script,also I want to play with it in my game for a while,because I like it very much and just want to see how it will be)
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);
	} ]

}
I don't get what I'm missing...One day I want to make AI like this one.I think the enemy does not attack me because my player is not scripted,and the one in Nirhis demo is.Can someone PLEASE tell me what can possibly be wrong.

Re: I'm Trying To Understand Why Is This Happening.

Posted: Tue Jun 17, 2008 6:32 pm
by bernie
In your Spawn routine try the high level command... HostilePlayer(true);

Re: I'm Trying To Understand Why Is This Happening.

Posted: Tue Jun 17, 2008 7:09 pm
by metal_head
I have already tried it and nothing happens,that's I'm asking you guys...that's really strange it's like the player isn't in the level

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 5:13 pm
by Jay
From looking at the script i believe Juutis doesn't use the standard TargetOrder-system (So HostilePlayer(true) will not work). From what i gather from the script, he seems to use attributes to determine if a pawn can sense if the player or other pawns are there. He must use DamageArea(...) commands to reduce the alert-attributes, and when it comes to 0, the enemy senses you - this makes it very easy to implement thinghs like stealth, or that a pawn can 'hear' the player (you can also implement different loudnesses for different floors this way!)

The script will ONLY work with Juutis' script, not even with a standard cripted player.

This is a very good solution Juutis.

EDIT: metal_head, this post is VERY similar to the post you posted in Level Design & Entity Usage. I deleted the other post.

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 6:22 pm
by metal_head
DamageArea...Haven't heard aboud this one...Is there anybody who knows how it's working?
EDIT: metal_head, this post is VERY similar to the post you posted in Level Design & Entity Usage. I deleted the other post
In Level Design & Entity Usage...I don't remember posting a script question there...I must have been really sleepy :D well sorry about that

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 6:29 pm
by Juutis
It's been a while since I've messed around with RF, but if I remember correctly there's a pawn called 'TARGET' that follows the player around and the enemies are actually shooting at it, not the player. So, I think changing

Code: Select all

SetTarget("TARGET");
to

Code: Select all

SetTarget("Player");
Should let the pawn see the built-in player (whose entityname is 'Player').


Jay wrote:From looking at the script i believe Juutis doesn't use the standard TargetOrder-system (So HostilePlayer(true) will not work). From what i gather from the script, he seems to use attributes to determine if a pawn can sense if the player or other pawns are there. He must use DamageArea(...) commands to reduce the alert-attributes, and when it comes to 0, the enemy senses you - this makes it very easy to implement thinghs like stealth, or that a pawn can 'hear' the player (you can also implement different loudnesses for different floors this way!)
Exactly.
Also, this way dead enemies can alert alive enemies by dealing damage to the alert-attribute. Or already alerted enemies can alert non-alert enemies. The possibilities are limitless.
Jay wrote:This is a very good solution Juutis.
Thanks. :)

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 6:35 pm
by metal_head
That's so COOL,you should get payed for that (if you already are not) that's just genius!!!!
To bad I can't think of something so cool.
Code:
SetTarget("TARGET");

to

Code:
SetTarget("Player");
Well it was set to player,I set it to TARGET,because I added in the beginning a

Code: Select all

TARGET      [Player]
than I removed it and have forgotten to set it to Player again

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 7:19 pm
by Juutis
Oh, right. :D

Anyway

Code: Select all

SetTarget("TARGET");
would target an entity called 'TARGET', while

Code: Select all

SetTarget(TARGET);
fetches the data from the variable 'TARGET' (in this case, the string 'Player'), and target that entity. So the latter option would be the right one if you wanted to have it that way.



Also, my scripted player is called 'player' and the built-in player is 'Player'. There's a difference. In my original script it is

Code: Select all

SetTarget("player");
and changing that to

Code: Select all

SetTarget("Player");
should work.

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 9:39 pm
by metal_head
Well,I changed it,but no result.That's why I want to know what I'm missing.I saw that about the player and changed it before I posted the topic but it didn't work

Also take a look at the picture i Uploaded.Should the console be that way all the time?

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 10:05 pm
by Juutis
To tell you the truth, I have no clue why it won't work. Basically the pawn should attack the target defined with the SetTarget() command, no matter what. I'll try to figure out something tomorrow, I just came home a few hours ago after spending 2 weeks in the forest, so I'm pretty tired.
Also take a look at the picture i Uploaded.Should the console be that way all the time?
Yeah, that's just:

Code: Select all

debug(self.enemy_vis);
And it indicates that the pawn can't see his enemy.

Re: I'm Trying To Understand Why Is This Happening.

Posted: Wed Jun 18, 2008 10:49 pm
by metal_head
Yep that's why I actually wrote this topic,cause I'm learning simkin and I think that it should work,but i doesn't.I want to know what is it so if I'm making a script and have this problem I want to know what is it.

Oh yeah get a rest and tell me are you a programmer,because this script is just genius,I haven't seen something like it before! It's just amazing how many things I've learned just looking at it.I'm very very very far from making something like this AI,but simkin is getting clearer for me.I can't even make a simple script on my own yet,but for now I'm editing other scripts :) but everything with it's time.

Re: I'm Trying To Understand Why Is This Happening.

Posted: Mon Jun 23, 2008 5:14 pm
by Juutis
Oh, dumb me. I looked through the scripting commands and realized that there's a command called TargetPlayer(). Apparently you can't target the player with SetTarget(). So, replacing 'SetTarget('player');' with 'TargetPlayer();' should fix the problem.

Re: I'm Trying To Understand Why Is This Happening.

Posted: Mon Jun 23, 2008 7:15 pm
by metal_head

Code: Select all

TargetPlayer(true);
Right?

EDIT: Yep,it works,now the script got more awesome than it was :D (no,really)