Page 1 of 1

Scripting enemy

Posted: Wed Apr 02, 2014 9:10 pm
by Gamemaker
Hey! So me and my friend started a small project with RealityFactory again. It has been some years since I was on my last project "Adrenaline" (http://web.zone.ee/adrenaline/), so I can't remember some things anout scripting.
I started off with a basic enemie's AI, but now I have a problem. I want it to be like that:

1. I am in enemie's sight and it starts following me
2. I run behind a wall or object
3. Enemy continues following me by finding the nearest way to me

I can't find any way to make a pawn think of the nearest way. I only know the way to make them move randomly left or right when they have an obstacle on their way until they see me.

Is it possible to do it somehow?

Just in case, I post my script too:

Code: Select all

{

	IDLE			[idle]		// idle animation
	WALK			[walk]		// walk animation
	DIE			[die]		// die animation
	SHOOT			[shoot]		// shoot animation
	MISC1			[slump]		// misc1 animation

	GROUP			[enemy]
	HOSTILEPLAYER		[true]		// hostile to player
	HOSTILESAME		[false]		// hostile to same Pawn group
		
	HEALTHATTRIBUTE		[enemy_health]	// name of pawns health attribute
	HEALTH			[100]		// initial pawn health
	DAMAGEATTRIBUTE		[health]	// attribute damaged by attack
		
	FOV			[220]		// enemies field of view angle
	PROJECTILE		[pistol_shell]	// enemy shoots that projectile
	FIREJOINT		[Joint18]	// enemy shoots from this bone
	BOUNDINGBOXWIDTH	[40]		// bounding box width
	BOUNDINGBOXHEIGHT	[90]		// bounding box height

	SIGHTDIST		[600]		// while idleing enemy sees you at that distance
	SHOOTDIST		[300]		// in that range enemy shoots
	FOLLOWAFTERSIGHTED	[1500]		// when enemy is following sight distance increases
	
	RUNSPEED		[200]		// enemy runs towards you with that speed
	ROTATESPEED		[200]		// enemy rotates at you with that speed


Spawn[()
{	
	Console(true);
	BoxWidth(BOUNDINGBOXWIDTH);
	BoxHeight(BOUNDINGBOXHEIGHT);
	SetFOV(FOV);
	AddCollisionOrder("rotate");
	AddPainOrder("Alert", 100);
	AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Die");
	FindTargetOrder(SIGHTDIST, "Alert", "health");
	PlayerDistOrder(SHOOTDIST, "rotate");
	NewOrder("Start");
}]



	Start[()
	{
		PlayAnimation(IDLE, true, "");
		RestartOrder();
	}]


Alert[()
{
	AnimateStop(SHOOT, 0, "pump.wav");
	if(self.player_range < SHOOTDIST)  // IT SEES ME AND IM CLOSER THAN 300
	{
		LowLevel("start_shooting");  // IT STARTS SHOOTING ME...
	}


			else 			     // IT SEES ME BUT I AM FURTHER THAN 300
			{
				NewOrder("MoveToPlayer");    // IT STARTS FOLLOWING ME
				RestartOrder();
			}
}]




LostTarget[()
{	
	FindTargetOrder(SIGHTDIST, "Alert", "health");
	PlayAnimation(IDLE, true, "");
	RestartOrder();
}]


PlayerKilled[()
{
	PlayAnimation(IDLE, true, "");
	RestartOrder();
}]	

Die[()
{
	SetNoCollision();
	AnimateStop(DIE, 3, "die1.wav");
	FadeOut(3, 0);
	Remove(true);
}]








//MOVEMENT


MoveToPlayer[()
{
LowLevel("start_following");
}]



		start_following[()
		{
		Animate("walk");
		self.ThinkTime = 0;
		self.ideal_yaw = self.enemy_yaw;
		self.yaw_speed = RUNSPEED;
		self.think = "follow";
		}]



follow[()
{

	self.ThinkTime = 0;

	if(self.health <= 0)
	{
		HighLevel("Die");
		return 0;
	}



	if(self.player_range > FOLLOWAFTERSIGHTED)
	{
		HighLevel("LostTarget");
		return 0;
	}




	if (self.player_range < SHOOTDIST)
	{
		self.think = "start_shooting";
		return 0;
	}



	if(self.enemy_vis = true)
	{
		self.ideal_yaw = self.enemy_yaw;
		ChangeYaw();
	}



		else
		{
			HighLevel("LostTarget");
			return 0;
		}




	if(self.animate_at_end = false)
	{
		walkmove(self.ideal_yaw, RUNSPEED);
	}



}]



//END OF MOVEMENT




//ATTACK
//ENEMY SAW A PLAYER AND SHOOTS IT


start_shooting[()
{

	if(EnemyExist("health") < 3)
	{
			HighLevel("PlayerKilled");
			return 0;
	}

	self.yaw_speed = 150;
	UpdateEnemyVis();
	UpdateTarget();


	if(self.enemy_vis = true)
	{
		self.ideal_yaw = self.enemy_yaw;
		ChangeYaw();
		Animate("shoot");
		SetHoldAtEnd(true);
		self.ThinkTime = 0.05;
		self.think = "shooting";
	}
	
		else
		{
			HighLevel("LostTarget");
		}

}]



shooting[()
{
	

	if(self.health <= 0)
	{
		HighLevel("Die");
		return 0;
	}
	

	self.ThinkTime = 0.4;

	switch(random(0,4))
	{
		case 0
		{
		FireProjectile(PROJECTILE, FIREJOINT, 0, 30, 0, "health", "0.5");
		}
	
		case 1
		{
		FireProjectile(PROJECTILE, FIREJOINT, -10, 0, 0, "health", "1");
		}

		case 2
		{
		FireProjectile(PROJECTILE, FIREJOINT, -5, 0, 0, "health", "0.8");
		}

		case 3
		{
		FireProjectile(PROJECTILE, FIREJOINT, 5, 0, 0, "health", "0.1");
		}

		case 4
		{
		FireProjectile(PROJECTILE, FIREJOINT, 10, 30, 0, "health", "0.9");
		}

	}

	self.think = "rotation_and_start_shooting";

}]



rotation_and_start_shooting[()
{
	HighLevel("rotate");
}]



rotate[()
{
	RotateToPlayer(IDLE, ROTATESPEED, false, "");

	if(self.player_range > SHOOTDIST)
	{
		NewOrder("MoveToPlayer");
	}
		
		else
		{
			LowLevel("start_shooting");
		}

}]



//END OF ATTACK

}

Re: Scripting enemy

Posted: Wed Apr 02, 2014 11:23 pm
by Allanon
Place Script Points at intersections and hard to navigate areas of the level and as the player runs past the Script Points update the Script Point's vector angle to point the direction the Player went. Then have the Enemy AI follow the vectors when chasing the Player. Also, since the Y vector angle is used for up and down and not needed to indicate the direction you can probably encode other information in to that value such as the time the Player went by. This would allow you to compare Script Points that are close to each other and see which one he went by last. Also be sure to zero the Script Point's vector angle as the Enemy AI goes by them so it doesn't stumble upon that Script Point again and mistake it for the direction the Player went.

Re: Scripting enemy

Posted: Sat Apr 05, 2014 1:15 pm
by Gamemaker
Could you give me some exact commands for that? When I used GetYawToPoint(); and GetPitchToPoint(); and then used walkmove to make the pawn move. What happened was that there was no rotation and pawn started moving just backwards.

Re: Scripting enemy

Posted: Sun Apr 06, 2014 12:03 am
by Allanon
Try using RotateToAlign(); it will rotate the pawn to the direction of the current script point.

Or you can just check the angle of the yaw:
0-10 degrees then player went forward
11-150 degrees then player went right
151-170 degrees then player went back
171-350 degrees then player went left
351-360 degrees then player went forward