My alllies wont die :O

Topics regarding Scripting with Reality Factory
Post Reply
User avatar
darksmaster923
Posts: 1857
Joined: Wed Jan 03, 2007 10:32 pm
Location: Huntington Beach, California, USA

My alllies wont die :O

Post by darksmaster923 »

well the title pratically sums it up. my allies WILL get hurt, blood spurts out unrealistically and they lose more blood than the human body has................but they just wont die <_<. the enemies they make short work of but my allies wont die at all.
Ally script

Code: Select all

{

	// Allied Bot Script
	// Made from Generic missile monster 

	GROUP				[Allies]	// name of monster group
	BOXWIDTH			[40]		// width and depth of bounding box
	HOSTILEPLAYER			[false]		// hostile to player
	HOSTILEDIFFERENT		[true]		// hostile to different Pawn group
	HOSTILESAME			[false]		// hostile to same Pawn group
	HOSTILETOGROUP			[enemy]		// hostile to this group
	HEALTHATTRIBUTE			[playerhealth]	// name of health attribute
	HEALTH				[25]		// initial amount of health
	SIGHTDIST			[3000]		// max distance monster can see at idle
	ALERTSIGHTDIST			[3000]		// max distance monster can see when alert
	FOV				[180]		// field of view in degrees
	YAWSPEED			[120]		// speed of rotation in deg/sec
	DAMAGEATTRIBUTE			[enemy_health]	// attribute damaged by attack
	ALERTTRIGGER			[AlertG]	// name of alert trigger
	SCALE				[1.4]		// amount to scale actor by
	
	SPAWNPOINT			[spawn_good]	// spawnpoint no 1
	SPAWNPOINT2			[spawn_good2]	// spawnpoint no 2
	FIRSTPOINT			[null]

	STAND				[idle]		// idle animation
	TURNL				[idle]		// turn left animation
	TURNR				[idle]		// turn right animation

	PAIN				[pain]		// pain animations
	PAIN1				[pain]
	PAIN2				[pain]
	PAIN3				[pain]
	PAINPERCENT			[0]		// percentage of time pain is shown

	DIE				[die]		// dying animations
	DIE1				[die2]
	DIE2				[die]
	DIE3				[die2]
	DIEHOLD				[5]		// time corpse still appears
	DIEFADE				[10]		// fadeout time of corpse
	KILLERX				[0]		// X pos of enemy before death
	KILLERY				[0]		// Y pos of enemy before death
	KILLERZ				[0]		// Z pos of enemy before death
	KILLER				[null]		// name o killer

	RUN				[run]		// running animation
	RUNSPEED			[300]		// average run speed
	RUNSOUND			[breath.wav]	

	WALK				[walk]		// walking animation
	WALKSPEED			[200]		// average walk speed

	WEAPON1				[M16_bot]
	WEAP1MAG			[30]
	WEAPON2				[FAMAS_bot]
	WEAP2MAG			[25]
	WEAPON3				[AWP_BOT]	// Sniper Weapon
	WEAP3MAG			[10]
	WEAPON4				[MP7_BOT]
	WEAP4MAG			[40]
	WEAPON5				[ump_bot]
	WEAP5MAG			[25]
	CURRENTWEAPAMMO			[0]
	ATTACKRANGE			[3000]
	SIGHTRANGE			[3400]
	RELOADTIME			[2]
	CLIPSIZE			[0]
	BULLET				[bad_shell]
	FIREBONE			[BIP01]
	WEAPON				[0]

	MISSILEATTACK			[shoot]		// missile attacking animation
	SHOOTUP				[shoot1]
	SHOOTDOWN			[shoot2]
	STRAFE				[strafe]	// strafeing animation
	RELOAD				[reload]	// reload animation
	SNIPERRANGE			[5000]		// distance for sniper rifle
	MISSILERANGE			[3400]		// max distance to start missile attack
	PROJECTILE			[rifle_shell]		// projectile name
	FIREBONE			[BIP01 R HAND]	// projectile launch bone
	OFFSETX				[0]		// launch offsets
	OFFSETY				[0]
	OFFSETZ				[0]
	ATTACKDELAY			[1]		// time between shots
	FIREDELAY			[0.8]		// delay after animation starts before projectile launch
	SKILL				[0]		// skill level 1 to 10

	LOSTTIME			[15]		// time to search for enemy before giving up
	POINTRADIUS			[20]		// radius from point when considered there
	INSIDEKOTH			[false]		// trigger koth


	// local variables - do not change

	
	RUNFUNC				[monster_run_start]		// monster run to attack function
	MISSILEFUNC			[monster_missile_start]		// monster missile function
	LOSTFUNC			[monster_lost_target_start]	// monster lost target function

	AS_NONE				[0]
	AS_MISSILE			[2]
	AS_STRAIGHT			[3]
	attack_delay			[0]
	lost_time			[0]
	back_up				[false]
	back_time			[0]
	left_time			[0]
	back_flag			[false]
	fire_delay			[0]
	skill_time			[0]
	attack_state			[0]
	lastorder			[null]
	lastanim			[null]
	killed				[false]

	// spawn pawn and do setup work

	Spawn[ ()
	{
		Console(true);
		BoxWidth(BOXWIDTH);						// set bounding box width/depth
		Scale(SCALE);							// scale actor
		AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Death");		// give monster health
		HostilePlayer(HOSTILEPLAYER);					// set who monster is hostile to
		HostileSame(HOSTILESAME);
		HostileDifferent(HOSTILEDIFFERENT);
		TargetGroup(HOSTILETOGROUP);
		AvoidOrder("Avoidance");
		switch(random(1,5))		// lets bot choose between 5 weapons
		{
			case 1
			{
				SetWeapon("M16_bot");
				WEAPON = 1;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP1MAG + 0;
			}
			case 2
			{
				SetWeapon("FAMAS_bot");
				WEAPON = 2;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP2MAG + 0;
			}
			case 3
			{
				SetWeapon("AWP_BOT");		// Sets Sniping Weapon
				WEAPON = 3;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP3MAG + 0;
			}
			case 4
			{
				SetWeapon("MP7_BOT");
				WEAPON = 4;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP4MAG + 0;
			}
			case 5
			{
				SetWeapon("ump_bot");
				WEAPON = 5;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP5MAG + 0;
			}
		}
		CLIPSIZE = CURRENTWEAPAMMO + 0;
		FIRSTPOINT = self.point_name;
		SetFOV(FOV);							// set field of view
		SetGroup(GROUP);						// assign a group to belong to
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// seen a target to chase
		AddPainOrder("IdlePain", 100);					// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered 
		NewOrder("Patrol");
	} ]

	DieSpawn[ ()
	{
		Console(true);
		BoxWidth(BOXWIDTH);						// set bounding box width/depth
		HostilePlayer(HOSTILEPLAYER);					// set who monster is hostile to
		HostileSame(HOSTILESAME);
		HostileDifferent(HOSTILEDIFFERENT);
		TargetGroup(HOSTILETOGROUP);
		AvoidOrder("Avoidance");
		CURRENTWEAPAMMO = CLIPSIZE + 0;
		NewPoint(FIRSTPOINT);
		SetFOV(FOV);							// set field of view
		SetGroup(GROUP);						// assign a group to belong to
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// seen a target to chase
		AddPainOrder("IdlePain", 100);					// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered 
		if(random(1,10) < 6)
		{
			NewOrder("Patrol");
		}
		else
		{
			FindPointOrder("Patrol");
		}
	} ]

	Patrol[ ()
	{
		RotateMoveToPoint(RUN, YAWSPEED, RUNSPEED*SCALE, false, RUNSOUND);
		MoveToPoint(RUN, RUNSPEED*SCALE, RUNSOUND);
		FindTargetOrder(4000, "FoundTarget", "enemy_health" );
		AvoidOrder("Avoidance");
		AddPainOrder("IdlePain", 100);
		NextPoint();
		RestartOrder();
	} ]

	Avoidance[ ()
	{
		if(random(1,10) < 5)
		{
			MoveForward(RUN, RUNSPEED, 100, RUNSOUND);		// Runs forward
			MoveRight(RUN, RUNSPEED, 100, RUNSOUND );
			Jump(RUN, 50, true, RUNSOUND );
			AddTimerOrder(1, 10, "CheckForPoints" );
		}
		else
		{
			MoveForward(RUN, RUNSPEED, 100, RUNSOUND);		// Run forward
			MoveLeft(RUN, RUNSPEED, 100, RUNSOUND );
			AddTimerOrder(1, 10, "CheckForPoints" );
		}
		Return();
	} ]

	CheckForPoints[ ()
	{
		if(self.point_vis)
		{
			NewOrder("Patrol");
		}
		else
		{
			FindPointOrder("Patrol");
		}
	} ]		

	// show pain at idle then trigger to alert

	IdlePain[ ()
	{
		switch(random(1,4)) // chose between 4 animations
		{
			case 1
			{
				PlayAnimation(PAIN, true, "");
			}
			case 2
			{
				PlayAnimation(PAIN1, true, "");
			}
			case 3
			{
				PlayAnimation(PAIN2, true, "");
			}
			case 4
			{
				PlayAnimation(PAIN3, true, "");
			}
		}
		NewOrder("FoundTarget");
	} ]	

	// start shifting from idle to alert

	IdleToAlert[ ()
	{
		FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// increase viewing distance
		AddPainOrder("AlertPain", PAINPERCENT);					// show pain
		AddTimerOrder(1, 10, "AlertToIdle");					// go to idle after 10 secs
		SetEventState(ALERTTRIGGER, false);					// turn off alert trigger
		NewOrder("Patrol");
	} ]

	// look around at alert looking for enemy

	Alert[ ()
	{
		FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);
		PlayAnimation(STAND, true, "");
		if(random(1,10)>3) // turn around once in awhile
		{
			if(random(1,10)>5)
			{
				Rotate(TURNL, 102, 0, 90, 0, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
			}
			else
			{
				Rotate(TURNR, 108, 0, -90, 0, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
			}
		}
		RestartOrder();
	} ]	

	// show pain at alert

	AlertPain[ ()
	{
		switch(random(1,4)) // play on of 4 animations
		{
			case 1
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				PlayAnimation(PAIN, true, "");
			}
			case 2
			{
				AddExplosion("blood2",FIREBONE,0,0,0);
				PlayAnimation(PAIN1, true, "");
			}
			case 3
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,0,0);
				PlayAnimation(PAIN2, true, "");
			}
			case 4
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,50,0);
				PlayAnimation(PAIN3, true, "");
			}
		}
		Return();
	} ]	

	// timed out at alert so go to idle

	AlertToIdle[ ()
	{
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// decrease viewing distance
		AddPainOrder("IdlePain", 100);					// show pain 
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered
		NewOrder("Patrol");
	} ]

	// found a target to attack

	FoundTarget[ ()
	{
		DelTimerOrder(1);	// get rid of alert timer
		LowLevel(RUNFUNC);	// attack functions are low level
	} ]

	// lost target while attacking so go back to idle again

	LostTarget[ ()
	{
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// seen a target to chase
		AddPainOrder("IdlePain", 100);					// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered
		NewOrder("Patrol");
	} ]

	// you died

	Death[ ()
	{
		killed = true;
		AddExplosion("blood",FIREBONE,0,0,0);
		AddExplosion("blood2",FIREBONE,0,50,0);
		if(random(1,10) < 6)
		{
			AnimateStop(DIE,DIEHOLD, "speak/imdieing.wav");
		}
		else
		{
			AnimateStop(DIE1,DIEHOLD, "die.wav");
		}
		ModifyAttribute("terr", 1, "Player");
		if(random(1,10) < 6)
		{			
                	TeleportToPoint(SPAWNPOINT,0,0,0);
		}
		else
		{			
                	TeleportToPoint(SPAWNPOINT2,0,0,0);
		}
        	SetAttribute(HEALTHATTRIBUTE,HEALTH); 
		NewOrder("DieSpawn");
	} ]

	// Low level attack routines

	// Start of run to attack

	monster_run_start[ ()
	{
		Animate(RUN);					// play run animation
		self.ThinkTime = 0;				// start thinking on next frame
		self.think = "monster_run";			// go to run attack routine
		self.ideal_yaw = enemy_yaw;			// set direction to run
		self.yaw_speed = YAWSPEED;			// set rotation speed
		back_up = false;				// initialize obsticle avoidance
		attack_state = AS_NONE;				// not attacking yet
	} ]

	// run to enemy to attack

	monster_run[ ()
	{
		if(self.health<=0)
		{
			drop();
			HighLevel("Death"); // dead
			return 0;
		}
		if(EnemyExist(DAMAGEATTRIBUTE) < 3)
		{
			HighLevel("LostTarget"); // enemy is gone or dead
			return 0;
		}
		if(self.enemy_range < ATTACKRANGE)
		{
			self.think = "monster_missile_start";
			return 0;
		}
		if(enemy_vis = false)
		{
			self.think = LOSTFUNC; // lost sight of enemy
			lost_time = time + LOSTTIME;
			return 0;
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "run_reload";
		}
		if(random(1,10) < 2)
		{
			PlaySound("speak/wehavehostiles.wav",1000);
		}
		ai_run(random(RUNSPEED-2,RUNSPEED+2)); // run toward enemy
	} ]

	run_reload[ ()
	{
		ai_face();
		SetHoldAtEnd(true);
		if(self.animate_at_end)
		{
			CURRENTWEAPAMMO = CLIPSIZE + 0;
			self.think = "monster_run";
		}		
	} ]

	// start of lost sight of enemy routine

	monster_lost_target_start[ ()
	{
		Animate(RUN); // play run animation
		self.ThinkTime = 0;					// start thinking on next frame
		self.think = "monster_lost_target";
	} ]

	// go to last known location of enemy

	monster_lost_target[ ()
	{
		self.ThinkTime = 0.1;
		if(lost_time<time)
		{
			HighLevel("LostTarget"); // timed out while looking
			return 0;
		}
		if(self.health<=0)
		{
			drop();
			HighLevel("Death"); // died
			return 0;
		}
		if(self.in_pain = true and (random(1,10) < 1))
		{
			if(random(1,10) < 2)
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,50,0);
				PlaySound("speak/backup.wav", 1000);
			}
		}
		if(EnemyExist(DAMAGEATTRIBUTE) < 3)
		{
			HighLevel("LostTarget"); // enemy died or was removed
			return 0;
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "lost_reload";
		}
		if(enemy_vis = true)
		{
			if(random(1,10)>5)
			{
				PlaySound("speak/attack.wav", 1000);
			}
			else
			{
				PlaySound("speak/wehavehostiles.wav", 1000);
			}
			self.think = "monster_run_start"; // seen again so run to attack
			self.ThinkTime = 0;
			return 0;
		} 
		if(enemy_range>POINTRADIUS) // get close to last known location
		{
			walk_movetogoal(random(RUNSPEED-2,RUNSPEED+2));
		} 
		else
		{
			HighLevel("LostTarget"); // can't find at last known location
			return 0;
		}
	} ]

	// Reload the weapon

	lost_reload[ ()
	{
		ai_face();
		SetHoldAtEnd(true);
		if(self.animate_at_end)
		{
			CURRENTWEAPAMMO = CLIPSIZE + 0;
			self.think = "monster_lost_target_start";
		}		
	} ]

	// start of missile attack

	monster_missile_start[ ()
	{
		if(WEAPON = 3)
		{
			Animate(MISSILEATTACK); // play missile attack animation
			SetHoldAtEnd(true);
			self.ThinkTime = 0;
			self.think = "sniper_shoot";
			fire_delay = time + FIREDELAY; // set firing delay
			UpdateTarget();					// update target location
			skill_time = time + (SKILL*0.1);		// calculate next update time
			attack_delay = time + ATTACKDELAY;		// delay until next shot
		}
		else
		{	
			Animate(MISSILEATTACK); // play missile attack animation
			SetHoldAtEnd(true);
			self.ThinkTime = 0;
			self.think = "monster_missile";
			fire_delay = time + FIREDELAY; // set firing delay
			UpdateTarget();					// update target location
			skill_time = time + (SKILL*0.1);		// calculate next update time
			attack_delay = time + ATTACKDELAY;		// delay until next shot
		}
	} ]

	sniper_shoot[ ()
	{
		self.ThinkTime = 0.1;		
		if(self.health<=0)
		{
			SetHoldAtEnd(false);
			drop();
			HighLevel("Death"); 	// dead
			return 0;
		}
		exist = EnemyExist(DAMAGEATTRIBUTE);
		if(exist < 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead and gone
			return 0;
		}
		if(exist = 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead but body remains
			return 0;
		}
		if(self.enemy_vis = false)
		{
			self.think = LOSTFUNC; 	// lost sight of enemy
			lost_time = self.time + LOSTTIME;
			SetHoldAtEnd(false);
			return 0;
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "shoot_reload";
		}
		if(self.enemy_range>SNIPERRANGE)
		{
			self.think = RUNFUNC; 	// too far away so run toward
			SetHoldAtEnd(false);
			return 0;
		}		
		if(skill_time<self.time) 	// update according to skill level
		{
			UpdateTarget();		// update target location
			skill_time = self.time + (SKILL*0.1);
			ai_face();		// face enemy while attacking
		}
		if(fire_delay<self.time) 	// delay after animation starts before firing
		{
			FireProjectile("sniper_shell", FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav", 500);
			SetHoldAtEnd(false);
			fire_delay = self.time + 1; 	// set delay well ahead so it is ignored
		}

	} ]

	// attack target with projectile

	monster_missile[ ()
	{
		self.ThinkTime = 0.2;
		debug(CURRENTWEAPAMMO);
		if(self.health<=0)
		{
			drop();
			SetHoldAtEnd(false);
			HighLevel("Death"); // dead
			return 0;
		}
		if(self.in_pain = true and (random(1,10) < 1))
		{
			if(random(1,10) < 2)
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,50,0);
			}
		}
		exist = EnemyExist(DAMAGEATTRIBUTE);
		if(exist < 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead and gone
			return 0;
		}
		if(exist = 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead but body remains
			return 0;
		}
		if(enemy_vis = false)
		{
			self.think = LOSTFUNC; // lost sight of enemy
			lost_time = time + LOSTTIME;
			SetHoldAtEnd(false);
			return 0;
		}
		if(enemy_range>MISSILERANGE)
		{
			self.think = RUNFUNC; // too far away so run toward
			SetHoldAtEnd(false);
			return 0;
		}
		if(skill_time < time) // update according to skill level
		{
			UpdateTarget();		// update target location
			skill_time = time + (SKILL*0.1);
			ai_face();	// face enemy while attacking
		}
		if(enemy_range<MISSILERANGE) // delay after animation starts before firing
		{
			UpdateTarget();		// update target location
			Animate(MISSILEATTACK);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			SetTargetPoint(random(-20,20),1000*sin(-self.enemy_pitch) + random(-20,20) + 20,1000*cos(self.enemy_pitch) + random(-20,20));
			FireProjectile(PROJECTILE,"BIP01",0,0,0,"enemy_health");
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav");
		}
		if(self.enemy_Y > Integer(self.current_Y + 100))
		{
			UpdateTarget();		// update target location
			Animate(SHOOTUP);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			FireProjectile("bad_shell", "BIP 01", 0, 0, 25, "enemy_health");
			AddExplosion("Muzzleflash2","BIP 01 R HAND",0,0,0);
			PlaySound("good.wav", 500);
			SetHoldAtEnd(false);
		}
		if(self.enemy_Y < Integer(self.current_Y - 100))
		{
			UpdateTarget();		// update target location
			Animate(SHOOTDOWN);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, "enemy_health");
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav", 500);
			SetHoldAtEnd(false);
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "shoot_reload";
		}
		if(random(1,10) <2)
		{
			Animate(STRAFE);
			if(random(1,10) < 6)
			{
				ForceLeft(30);
				return 0;
			}
			else
			{
				ForceRight(30);
				return 0;
			}
		}
		if(fire_delay<time) 				// delay after animation starts before firing
		{
			if(random(1,10) < 5)
			{
				Animate(STRAFE);
				ForceRight(10);
				return 0;
			}
			else
			{
				Animate(STRAFE);
				ForceLeft(10);
				return 0;
			}
			UpdateTarget();		// update target location
			Animate(MISSILEATTACK);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			SetTargetPoint(random(-20,20),1000*sin(-self.enemy_pitch) + random(-20,20) + 20,1000*cos(self.enemy_pitch) + random(-20,20));
			FireProjectile(PROJECTILE,"BIP01",0,0,0,"enemy_health");
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav");
		}
		if(self.animate_at_end = true)
		{
			if(attack_delay < time)
			{
				self.think = "monster_missile_start"; // go back to missile attack
				SetHoldAtEnd(false);
				self.ThinkTime = 0.1;
			}
		} 
	} ]

	// Reload the weapon

	shoot_reload[ ()
	{
		ai_face();
		SetHoldAtEnd(true);
		if(self.animate_at_end)
		{
			CURRENTWEAPAMMO = CLIPSIZE + 0;
			self.think = "monster_missile_start";
		}		
	} ]

	// Drop that gun soldier
	drop[ ()
	{
		if(WEAPON = 1)
		{
			SetPosition("m16", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 2)
		{
			SetPosition("famas", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 3)
		{
			SetPosition("awp", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 4)
		{
			SetPosition("mp7", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 5)
		{
			SetPosition("ump", self.current_X, self.current_Y, self.current_Z);
		}
	} ]

	// If the bot is in side the koth area

	insidekoth[ ()
	{
		if(GetDistanceTo("hill") < 1000)
		{
			INSIDEKOTH = true;
			HighLevel("Camp");
			return 0;
		}
	} ]

	Camp[ ()
	{
		if(INSIDEKOTH = true)
		{
			FindTargetOrder(SIGHTRANGE, "FoundTarget", DAMAGEATTRIBUTE);
			if(random(1,10) < 3)
			{
				Rotate(TURNL, random(1,180), 0, random(1,90), 0, "");
			}
		}
		else
		{
			NewOrder("Patrol");
		}
	} ]
	// basic AI routines

	// run toward enemy and see if you are ready to attack

	ai_run[ (dist)
	{
		if (attack_state = AS_MISSILE) // do missile attack
		{
			ai_run_missile();
			return 0;
		}
		if (CheckAnyAttack()) // check if you can start the actual attack
		{
			return 0;
		}
		walk_movetogoal(dist); // else move toward the enemy
	} ]

	// missile attack setup

	ai_run_missile[ ()
	{
		ai_face();
		if(FacingIdeal()) // got close enough
		{
			self.think = MISSILEFUNC;	// start missile attack
			attack_state = AS_STRAIGHT;
			UpdateTarget();
			skill_time = time + (SKILL*0.1);
		}
	} ]

	// face enemy

	ai_face[ ()
	{
		self.ideal_yaw = enemy_yaw;
		ChangeYaw(); // rotate to face enemy
	} ]

	// use walkmove to naviagte to enemy

	walk_movetogoal[ (dist)
	{
		if(IsFalling = true)
		{
			return 0;	// don't move while falling
		} 
		if(back_up = false)
		{
			ai_face();	// turn to face enemy
			if(FacingIdeal())
			{
				if(walkmove(self.current_yaw, dist) = true)
				{
					return 0;	// can move in current direction
				}
				else
				{
					if(random(1,10)<3)	// backup and move sideways
					{
						back_up = true;
						back_time = time + 0.5;
						back_flag = false;
						return 0;
					}
					else 
					{ 
						ForceUp(30);	// jump up, forward and to side
						ForceForward(30);
						if(random(1,10)<6)
						{
							ForceRight(30);
						}
						else
						{
							ForceLeft(30);
						} 
					} 
				} 
			}
		}
		else
		{
			if(back_flag = false) // go backward 1/2 sec
			{
				if(back_time > time)
				{
					walkmove((self.current_yaw-(180*0.0174532925199433)), dist);
					return 0;
				}
				else
				{
					back_time = time + 0.5;
					back_flag = true;
				}
			}
			if(back_time > time) // go sideways 1/2 sec
			{
				walkmove((self.current_yaw-(90*0.0174532925199433)), dist);
				return 0;
			}
			back_up = false;
		}
	} ]


	// check if nearly facing enemy

	FacingIdeal[ ()
	{
		selfangle = self.current_yaw/0.0174532925199433; // your direction in degrees
		idealangle = self.ideal_yaw/0.0174532925199433;	// his direction in degrees
		delta = selfangle - idealangle; // difference in directions
		if (delta > -20 and delta < 20) // within 20 degrees is close enough
		{
			return true;
		}
		return false;
	} ]

	// check if ready to do actual attacking

	CheckAnyAttack[ ()
	{
		if(attack_delay>time)
		{
			return false;
		}
		if(enemy_range<MISSILERANGE) // inside missile range
		{
			attack_state = AS_MISSILE; // do a missile attack
			return true;
		}
		return false;
	} ]
}


Enemy SCript

Code: Select all

{

	// Enemy Bot Script
	// Made from Generic missile monster 

	GROUP				[enemy]	// name of monster group
	BOXWIDTH			[40]		// width and depth of bounding box
	HOSTILEPLAYER			[true]		// hostile to player
	HOSTILEDIFFERENT		[true]		// hostile to different Pawn group
	HOSTILESAME			[false]		// hostile to same Pawn group
	HOSTILETOGROUP			[guy]		// hostile to this group
	HEALTHATTRIBUTE			[enemy_health]	// name of health attribute
	HEALTH				[100]		// initial amount of health
	SIGHTDIST			[500]		// max distance monster can see at idle
	ALERTSIGHTDIST			[600]		// max distance monster can see when alert
	FOV				[180]		// field of view in degrees
	YAWSPEED			[120]		// speed of rotation in deg/sec
	DAMAGEATTRIBUTE			[playerhealth]	// attribute damaged by attack
	ALERTTRIGGER			[AlertG]	// name of alert trigger
	SCALE				[1.4]		// amount to scale actor by
	
	SPAWNPOINT			[spawn_enemy]	// spawnpoint no 1
	SPAWNPOINT2			[spawn_enemy2]	// spawnpoint no 2
	FIRSTPOINT			[null]

	STAND				[idle]		// idle animation
	TURNL				[idle]		// turn left animation
	TURNR				[idle]		// turn right animation

	PAINPERCENT			[0]		// percentage of time pain is shown

	DIE				[die]		// dying animations
	DIE1				[die2]
	DIE2				[die]
	DIE3				[die2]
	DIEHOLD				[5]		// time corpse still appears
	DIEFADE				[10]		// fadeout time of corpse
	KILLERX				[0]		// X pos of enemy before death
	KILLERY				[0]		// Y pos of enemy before death
	KILLERZ				[0]		// Z pos of enemy before death
	KILLER				[null]		// name o killer

	RUN				[run]		// running animation
	RUNSPEED			[300]		// average run speed
	RUNSOUND			[breath.wav]	

	WALK				[walk]		// walking animation
	WALKSPEED			[200]		// average walk speed

	WEAPON1				[ak_bot]
	WEAP1MAG			[30]
	WEAPON2				[galil_bot]
	WEAP2MAG			[30]
	WEAPON3				[AWP_BOT]	// Sniper Weapon
	WEAP3MAG			[10]
	WEAPON4				[pp19_BOT]
	WEAP4MAG			[45]
	WEAPON5				[ump_bot]
	WEAP5MAG			[25]
	CURRENTWEAPAMMO			[0]
	ATTACKRANGE			[3000]
	SIGHTRANGE			[3400]
	RELOADTIME			[2]
	CLIPSIZE			[0]
	BULLET				[bad_shell]
	FIREBONE			[BIP01]
	WEAPON				[0]

	MISSILEATTACK			[shoot]		// missile attacking animation
	SHOOTUP				[shoot1]
	SHOOTDOWN			[shoot2]
	STRAFE				[strafe]	// strafeing animation
	RELOAD				[reload]	// reload animation
	SNIPERRANGE			[5000]		// distance for sniper rifle
	MISSILERANGE			[3400]		// max distance to start missile attack
	PROJECTILE			[rifle_shell]		// projectile name
	FIREBONE			[BIP01 R HAND]	// projectile launch bone
	OFFSETX				[0]		// launch offsets
	OFFSETY				[0]
	OFFSETZ				[0]
	ATTACKDELAY			[1]		// time between shots
	FIREDELAY			[0.8]		// delay after animation starts before projectile launch
	SKILL				[0]		// skill level 1 to 10

	LOSTTIME			[15]		// time to search for enemy before giving up
	POINTRADIUS			[20]		// radius from point when considered there
	INSIDEKOTH			[false]		// trigger koth


	// local variables - do not change

	
	RUNFUNC				[monster_run_start]		// monster run to attack function
	MISSILEFUNC			[monster_missile_start]		// monster missile function
	LOSTFUNC			[monster_lost_target_start]	// monster lost target function

	AS_NONE				[0]
	AS_MISSILE			[2]
	AS_STRAIGHT			[3]
	attack_delay			[0]
	lost_time			[0]
	back_up				[false]
	back_time			[0]
	left_time			[0]
	back_flag			[false]
	fire_delay			[0]
	skill_time			[0]
	attack_state			[0]
	lastorder			[null]
	lastanim			[null]
	killed				[false]

	// spawn pawn and do setup work

	Spawn[ ()
	{
		Console(true);
		BoxWidth(BOXWIDTH);						// set bounding box width/depth
		Scale(SCALE);							// scale actor
		AttributeOrder(HEALTHATTRIBUTE, HEALTH, "Death");		// give monster health
		HostilePlayer(HOSTILEPLAYER);					// set who monster is hostile to
		HostileSame(HOSTILESAME);
		HostileDifferent(HOSTILEDIFFERENT);
		TargetGroup(HOSTILETOGROUP);
		AvoidOrder("Avoidance");
		switch(random(1,5))		// lets bot choose between 5 weapons
		{
			case 1
			{
				SetWeapon("ak_bot");
				WEAPON = 1;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP1MAG + 0;
			}
			case 2
			{
				SetWeapon("galil_bot");
				WEAPON = 2;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP2MAG + 0;
			}
			case 3
			{
				SetWeapon("AWP_bot");		// Sets Sniping Weapon
				WEAPON = 3;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP3MAG + 0;
			}
			case 4
			{
				SetWeapon("pp19_bot");
				WEAPON = 4;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP4MAG + 0;
			}
			case 5
			{
				SetWeapon("ump_bot");
				WEAPON = 5;			// Weapon Number. Used in Attack cmds.
				CURRENTWEAPAMMO = WEAP5MAG + 0;
			}
		}
		CLIPSIZE = CURRENTWEAPAMMO + 0;
		FIRSTPOINT = self.point_name;
		SetFOV(FOV);							// set field of view
		SetGroup(GROUP);						// assign a group to belong to
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// seen a target to chase
		AddPainOrder("IdlePain", 100);					// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered 
		NewOrder("Patrol");
	} ]

	DieSpawn[ ()
	{
		Console(true);
		BoxWidth(BOXWIDTH);						// set bounding box width/depth
		HostilePlayer(HOSTILEPLAYER);					// set who monster is hostile to
		HostileSame(HOSTILESAME);
		HostileDifferent(HOSTILEDIFFERENT);
		TargetGroup(HOSTILETOGROUP);
		AvoidOrder("Avoidance");
		CURRENTWEAPAMMO = CLIPSIZE + 0;
		NewPoint(FIRSTPOINT);
		SetFOV(FOV);							// set field of view
		SetGroup(GROUP);						// assign a group to belong to
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// seen a target to chase
		AddPainOrder("IdlePain", 100);					// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered 
		if(random(1,10) < 6)
		{
			NewOrder("Patrol");
		}
		else
		{
			FindPointOrder("Patrol");
		}
	} ]

	Patrol[ ()
	{
		RotateMoveToPoint(RUN, YAWSPEED, RUNSPEED*SCALE, false, RUNSOUND);
		MoveToPoint(RUN, RUNSPEED*SCALE, RUNSOUND);
		FindTargetOrder(4000, "FoundTarget", "playerhealth" );
		AvoidOrder("Avoidance");
		AddPainOrder("IdlePain", 100);
		NextPoint();
		RestartOrder();
	} ]

	Avoidance[ ()
	{
		if(random(1,10) < 5)
		{
			MoveForward(RUN, RUNSPEED, 100, RUNSOUND);		// Runs forward
			MoveRight(RUN, RUNSPEED, 100, RUNSOUND );
			Jump(RUN, 50, true, RUNSOUND );
			AddTimerOrder(1, 10, "CheckForPoints" );
		}
		else
		{
			MoveForward(RUN, RUNSPEED, 100, RUNSOUND);		// Run forward
			MoveLeft(RUN, RUNSPEED, 100, RUNSOUND );
			AddTimerOrder(1, 10, "CheckForPoints" );
		}
		Return();
	} ]

	CheckForPoints[ ()
	{
		if(self.point_vis)
		{
			NewOrder("Patrol");
		}
		else
		{
			FindPointOrder("Patrol");
		}
	} ]		

	// show pain at idle then trigger to alert

	IdlePain[ ()
	{
		NewOrder("FoundTarget");
	} ]	

	// start shifting from idle to alert

	IdleToAlert[ ()
	{
		FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// increase viewing distance
		AddPainOrder("AlertPain", PAINPERCENT);					// show pain
		AddTimerOrder(1, 10, "AlertToIdle");					// go to idle after 10 secs
		SetEventState(ALERTTRIGGER, false);					// turn off alert trigger
		NewOrder("Patrol");
	} ]

	// look around at alert looking for enemy

	Alert[ ()
	{
		FindTargetOrder(ALERTSIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);
		PlayAnimation(STAND, true, "");
		if(random(1,10)>3) // turn around once in awhile
		{
			if(random(1,10)>5)
			{
				Rotate(TURNL, 102, 0, 90, 0, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
				Rotate(TURNL, 102, 0, 90, 0, "");
			}
			else
			{
				Rotate(TURNR, 108, 0, -90, 0, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
				Rotate(TURNR, 108, 0, -90, 0, "");
			}
		}
		RestartOrder();
	} ]	

	// show pain at alert

	AlertPain[ ()
	{
		switch(random(1,4)) // play on of 4 animations
		{
			case 1
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				PlayAnimation(PAIN, true, "");
			}
			case 2
			{
				AddExplosion("blood2",FIREBONE,0,0,0);
				PlayAnimation(PAIN1, true, "");
			}
			case 3
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,0,0);
				PlayAnimation(PAIN2, true, "");
			}
			case 4
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,50,0);
				PlayAnimation(PAIN3, true, "");
			}
		}
		Return();
	} ]	

	// timed out at alert so go to idle

	AlertToIdle[ ()
	{
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// decrease viewing distance
		AddPainOrder("IdlePain", 100);					// show pain 
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered
		NewOrder("Patrol");
	} ]

	// found a target to attack

	FoundTarget[ ()
	{
		DelTimerOrder(1);	// get rid of alert timer
		LowLevel(RUNFUNC);	// attack functions are low level
	} ]

	// lost target while attacking so go back to idle again

	LostTarget[ ()
	{
		FindTargetOrder(SIGHTDIST, "FoundTarget", DAMAGEATTRIBUTE);	// seen a target to chase
		AddPainOrder("IdlePain", 100);					// show pain and trigger alert
		AddTriggerOrder("IdleToAlert", ALERTTRIGGER, 0);		// go to alert when triggered
		NewOrder("Patrol");
	} ]

	// you died

	Death[ ()
	{
		killed = true;
		AddExplosion("blood",FIREBONE,0,0,0);
		AddExplosion("blood2",FIREBONE,0,50,0);
		if(random(1,10) < 6)
		{
			AnimateStop(DIE,DIEHOLD, "speak/imdieing.wav");
		}
		else
		{
			AnimateStop(DIE1,DIEHOLD, "die.wav");
		}
		ModifyAttribute("usmc", 1, "Player");
		if(random(1,10) < 6)
		{			
                	TeleportToPoint(SPAWNPOINT,0,0,0);
		}
		else
		{			
                	TeleportToPoint(SPAWNPOINT2,0,0,0);
		}
        	SetAttribute(HEALTHATTRIBUTE,HEALTH); 
		NewOrder("DieSpawn");
	} ]

	// Low level attack routines

	// Start of run to attack

	monster_run_start[ ()
	{
		Animate(RUN);					// play run animation
		self.ThinkTime = 0;				// start thinking on next frame
		self.think = "monster_run";			// go to run attack routine
		self.ideal_yaw = enemy_yaw;			// set direction to run
		self.yaw_speed = YAWSPEED;			// set rotation speed
		back_up = false;				// initialize obsticle avoidance
		attack_state = AS_NONE;				// not attacking yet
	} ]

	// run to enemy to attack

	monster_run[ ()
	{
		if(self.health<=0)
		{
			drop();
			HighLevel("Death"); // dead
			return 0;
		}
		if(EnemyExist(DAMAGEATTRIBUTE) < 3)
		{
			HighLevel("LostTarget"); // enemy is gone or dead
			return 0;
		}
		if(self.enemy_range < SHOOTRANGE)
		{
			self.think = "monster_missile_start";
			return 0;
		}
		if(enemy_vis = false)
		{
			self.think = LOSTFUNC; // lost sight of enemy
			lost_time = time + LOSTTIME;
			return 0;
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "run_reload";
		}
		if(random(1,10) < 2)
		{
			PlaySound("speak/wehavehostiles.wav",1000);
		}
		ai_run(random(RUNSPEED-2,RUNSPEED+2)); // run toward enemy
	} ]

	run_reload[ ()
	{
		ai_face();
		SetHoldAtEnd(true);
		if(self.animate_at_end)
		{
			CURRENTWEAPAMMO = CLIPSIZE + 0;
			self.think = "monster_run";
		}		
	} ]

	// start of lost sight of enemy routine

	monster_lost_target_start[ ()
	{
		Animate(RUN); // play run animation
		self.ThinkTime = 0;					// start thinking on next frame
		self.think = "monster_lost_target";
	} ]

	// go to last known location of enemy

	monster_lost_target[ ()
	{
		self.ThinkTime = 0.1;
		if(lost_time<time)
		{
			HighLevel("LostTarget"); // timed out while looking
			return 0;
		}
		if(self.health<=0)
		{
			drop();
			HighLevel("Death"); // died
			return 0;
		}
		if(self.in_pain = true and (random(1,10) < 1))
		{
			if(random(1,10) < 2)
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,50,0);
				PlaySound("speak/backup.wav", 1000);
			}
		}
		if(EnemyExist(DAMAGEATTRIBUTE) < 3)
		{
			HighLevel("LostTarget"); // enemy died or was removed
			return 0;
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "lost_reload";
		}
		if(enemy_vis = true)
		{
			if(random(1,10)>5)
			{
				PlaySound("speak/attack.wav", 1000);
			}
			else
			{
				PlaySound("speak/wehavehostiles.wav", 1000);
			}
			self.think = "monster_run_start"; // seen again so run to attack
			self.ThinkTime = 0;
			return 0;
		} 
		if(enemy_range>POINTRADIUS) // get close to last known location
		{
			walk_movetogoal(random(RUNSPEED-2,RUNSPEED+2));
		} 
		else
		{
			HighLevel("LostTarget"); // can't find at last known location
			return 0;
		}
	} ]

	// Reload the weapon

	lost_reload[ ()
	{
		ai_face();
		SetHoldAtEnd(true);
		if(self.animate_at_end)
		{
			CURRENTWEAPAMMO = CLIPSIZE + 0;
			self.think = "monster_lost_target_start";
		}		
	} ]

	// start of missile attack

	monster_missile_start[ ()
	{
		if(WEAPON = 3)
		{
			Animate(MISSILEATTACK); // play missile attack animation
			SetHoldAtEnd(true);
			self.ThinkTime = 0;
			self.think = "sniper_shoot";
			fire_delay = time + FIREDELAY; // set firing delay
			UpdateTarget();					// update target location
			skill_time = time + (SKILL*0.1);		// calculate next update time
			attack_delay = time + ATTACKDELAY;		// delay until next shot
		}
		else
		{	
			Animate(MISSILEATTACK); // play missile attack animation
			SetHoldAtEnd(true);
			self.ThinkTime = 0;
			self.think = "monster_missile";
			fire_delay = time + FIREDELAY; // set firing delay
			UpdateTarget();					// update target location
			skill_time = time + (SKILL*0.1);		// calculate next update time
			attack_delay = time + ATTACKDELAY;		// delay until next shot
		}
	} ]

	sniper_shoot[ ()
	{
		self.ThinkTime = 0.1;		
		if(self.health<=0)
		{
			SetHoldAtEnd(false);
			drop();
			HighLevel("Death"); 	// dead
			return 0;
		}
		exist = EnemyExist(DAMAGEATTRIBUTE);
		if(exist < 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead and gone
			return 0;
		}
		if(exist = 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead but body remains
			return 0;
		}
		if(self.enemy_vis = false)
		{
			self.think = LOSTFUNC; 	// lost sight of enemy
			lost_time = self.time + LOSTTIME;
			SetHoldAtEnd(false);
			return 0;
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "shoot_reload";
		}
		if(self.enemy_range>SNIPERRANGE)
		{
			self.think = RUNFUNC; 	// too far away so run toward
			SetHoldAtEnd(false);
			return 0;
		}		
		if(skill_time<self.time) 	// update according to skill level
		{
			UpdateTarget();		// update target location
			skill_time = self.time + (SKILL*0.1);
			ai_face();		// face enemy while attacking
		}
		if(fire_delay<self.time) 	// delay after animation starts before firing
		{
			FireProjectile("sniper_shell", FIREBONE, OFFSETX, OFFSETY, OFFSETZ, DAMAGEATTRIBUTE);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav", 500);
			SetHoldAtEnd(false);
			fire_delay = self.time + 1; 	// set delay well ahead so it is ignored
		}
	} ]

	// attack target with projectile

	monster_missile[ ()
	{
		self.ThinkTime = 0.2;
		debug(CURRENTWEAPAMMO);
		if(self.health<=0)
		{
			drop();
			SetHoldAtEnd(false);
			HighLevel("Death"); // dead
			return 0;
		}
		if(self.in_pain = true and (random(1,10) < 1))
		{
			if(random(1,10) < 2)
			{
				AddExplosion("blood",FIREBONE,0,0,0);
				AddExplosion("blood2",FIREBONE,0,50,0);
			}
		}
		exist = EnemyExist(DAMAGEATTRIBUTE);
		if(exist < 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead and gone
			return 0;
		}
		if(exist = 2)
		{
			SetHoldAtEnd(false);
			HighLevel("LostTarget"); // enemy is dead but body remains
			return 0;
		}
		if(enemy_vis = false)
		{
			self.think = LOSTFUNC; // lost sight of enemy
			lost_time = time + LOSTTIME;
			SetHoldAtEnd(false);
			return 0;
		}
		if(enemy_range>MISSILERANGE)
		{
			self.think = RUNFUNC; // too far away so run toward
			SetHoldAtEnd(false);
			return 0;
		}
		if(skill_time < time) // update according to skill level
		{
			UpdateTarget();		// update target location
			skill_time = time + (SKILL*0.1);
			ai_face();	// face enemy while attacking
		}
		if(enemy_range<MISSILERANGE) // delay after animation starts before firing
		{
			UpdateTarget();		// update target location
			Animate(MISSILEATTACK);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			SetTargetPoint(random(-10,10),1000*sin(-self.enemy_pitch) + random(-10,10) + 20,1000*cos(self.enemy_pitch) + random(-20,20));
			FireProjectile(PROJECTILE,"BIP01",0,0,0,"playerhealth");
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav");
		}
		if(self.enemy_Y > Integer(self.current_Y + 100))
		{
			UpdateTarget();		// update target location
			Animate(SHOOTUP);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			FireProjectile("bad_shell", "BIP 01", 0, 0, 25, "playerhealth");
			AddExplosion("Muzzleflash2","BIP 01 R HAND",0,0,0);
			PlaySound("good.wav", 500);
			SetHoldAtEnd(false);
		}
		if(self.enemy_Y < Integer(self.current_Y - 100))
		{
			UpdateTarget();		// update target location
			Animate(SHOOTDOWN);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			FireProjectile(PROJECTILE, FIREBONE, OFFSETX, OFFSETY, OFFSETZ, "playerhealth");
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav", 500);
			SetHoldAtEnd(false);
		}
		if(CURRENTWEAPAMMO < 1)
		{
			Animate(RELOAD);
			self.think = "shoot_reload";
		}
		if(random(1,10) <2)
		{
			Animate(STRAFE);
			if(random(1,10) < 6)
			{
				ForceLeft(30);
				return 0;
			}
			else
			{
				ForceRight(30);
				return 0;
			}
		}
		if(fire_delay<time) 				// delay after animation starts before firing
		{
			if(random(1,10) < 5)
			{
				Animate(STRAFE);
				ForceRight(10);
				return 0;
			}
			else
			{
				Animate(STRAFE);
				ForceLeft(10);
				return 0;
			}
			UpdateTarget();		// update target location
			Animate(MISSILEATTACK);
			CURRENTWEAPAMMO = CURRENTWEAPAMMO - 1;
			SetTargetPoint(random(-20,20),1000*sin(-self.enemy_pitch) + random(-20,20) + 20,1000*cos(self.enemy_pitch) + random(-20,20));
			FireProjectile(PROJECTILE,"BIP01",0,0,0,"playerhealth");
			AddExplosion("Muzzleflash2","BIP01 R HAND",0,0,0);
			PlaySound("good.wav");
		}
		if(self.animate_at_end = true)
		{
			if(attack_delay < time)
			{
				self.think = "monster_missile_start"; // go back to missile attack
				SetHoldAtEnd(false);
				self.ThinkTime = 0.1;
			}
		} 
	} ]

	// Reload the weapon

	shoot_reload[ ()
	{
		ai_face();
		SetHoldAtEnd(true);
		if(self.animate_at_end)
		{
			CURRENTWEAPAMMO = CLIPSIZE + 0;
			self.think = "monster_missile_start";
		}		
	} ]

	// Drop that gun soldier
	drop[ ()
	{
		if(WEAPON = 1)
		{
			SetPosition("m16", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 2)
		{
			SetPosition("famas", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 3)
		{
			SetPosition("awp", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 4)
		{
			SetPosition("mp7", self.current_X, self.current_Y, self.current_Z);
		}
		if(WEAPON = 5)
		{
			SetPosition("ump", self.current_X, self.current_Y, self.current_Z);
		}
	} ]

	// If the bot is in side the koth area

	insidekoth[ ()
	{
		if(GetDistanceTo("hill") < 1000)
		{
			INSIDEKOTH = true;
			HighLevel("Camp");
			return 0;
		}
	} ]

	Camp[ ()
	{
		if(INSIDEKOTH = true)
		{
			FindTargetOrder(SIGHTRANGE, "FoundTarget", DAMAGEATTRIBUTE);
			if(random(1,10) < 3)
			{
				Rotate(TURNL, random(1,180), 0, random(1,90), 0, "");
			}
		}
		else
		{
			NewOrder("Patrol");
		}
	} ]
	// basic AI routines

	// run toward enemy and see if you are ready to attack

	ai_run[ (dist)
	{
		if (attack_state = AS_MISSILE) // do missile attack
		{
			ai_run_missile();
			return 0;
		}
		if (CheckAnyAttack()) // check if you can start the actual attack
		{
			return 0;
		}
		walk_movetogoal(dist); // else move toward the enemy
	} ]

	// missile attack setup

	ai_run_missile[ ()
	{
		ai_face();
		if(FacingIdeal()) // got close enough
		{
			self.think = MISSILEFUNC;	// start missile attack
			attack_state = AS_STRAIGHT;
			UpdateTarget();
			skill_time = time + (SKILL*0.1);
		}
	} ]

	// face enemy

	ai_face[ ()
	{
		self.ideal_yaw = enemy_yaw;
		ChangeYaw(); // rotate to face enemy
	} ]

	// use walkmove to naviagte to enemy

	walk_movetogoal[ (dist)
	{
		if(IsFalling = true)
		{
			return 0;	// don't move while falling
		} 
		if(back_up = false)
		{
			ai_face();	// turn to face enemy
			if(FacingIdeal())
			{
				if(walkmove(self.current_yaw, dist) = true)
				{
					return 0;	// can move in current direction
				}
				else
				{
					if(random(1,10)<3)	// backup and move sideways
					{
						back_up = true;
						back_time = time + 0.5;
						back_flag = false;
						return 0;
					}
					else 
					{ 
						ForceUp(30);	// jump up, forward and to side
						ForceForward(30);
						if(random(1,10)<6)
						{
							ForceRight(30);
						}
						else
						{
							ForceLeft(30);
						} 
					} 
				} 
			}
		}
		else
		{
			if(back_flag = false) // go backward 1/2 sec
			{
				if(back_time > time)
				{
					walkmove((self.current_yaw-(180*0.0174532925199433)), dist);
					return 0;
				}
				else
				{
					back_time = time + 0.5;
					back_flag = true;
				}
			}
			if(back_time > time) // go sideways 1/2 sec
			{
				walkmove((self.current_yaw-(90*0.0174532925199433)), dist);
				return 0;
			}
			back_up = false;
		}
	} ]


	// check if nearly facing enemy

	FacingIdeal[ ()
	{
		selfangle = self.current_yaw/0.0174532925199433; // your direction in degrees
		idealangle = self.ideal_yaw/0.0174532925199433;	// his direction in degrees
		delta = selfangle - idealangle; // difference in directions
		if (delta > -20 and delta < 20) // within 20 degrees is close enough
		{
			return true;
		}
		return false;
	} ]

	// check if ready to do actual attacking

	CheckAnyAttack[ ()
	{
		if(attack_delay>time)
		{
			return false;
		}
		if(enemy_range<MISSILERANGE) // inside missile range
		{
			attack_state = AS_MISSILE; // do a missile attack
			return true;
		}
		return false;
	} ]
}

Herp derp.
User avatar
darksmaster923
Posts: 1857
Joined: Wed Jan 03, 2007 10:32 pm
Location: Huntington Beach, California, USA

Post by darksmaster923 »

no banana? i am literally banging my head against the wall about this
Herp derp.
morbidsouldotcom
Posts: 12
Joined: Sat Aug 11, 2007 7:15 am
Location: Pennsylvania
Contact:

Post by morbidsouldotcom »

Don't feel bad, no one will answer mine, either, lol
User avatar
zany_001
Posts: 1047
Joined: Fri Mar 02, 2007 8:36 am
Location: Aotearoa

Post by zany_001 »

did this always use to happen?because fi not,you should be able to work out wha you did to make you allies not die.
Once I was sad, and I stopped being sad and was awesome instead.
True story.
User avatar
darksmaster923
Posts: 1857
Joined: Wed Jan 03, 2007 10:32 pm
Location: Huntington Beach, California, USA

Post by darksmaster923 »

well i sorta solved it, i just put a random value on pain then call death order
Herp derp.
Post Reply