Module dpmod: Change committed

havoc at icculus.org havoc at icculus.org
Thu Feb 20 04:04:55 EST 2003


Commiter   : havoc
CVSROOT    : /cvs/cvsroot/twilight
Module     : dpmod
Commit time: 2003-02-20 09:04:55 UTC

Log message:

limited monster AI and creaturecode to only executing FindTarget and creaturecode and such on 200 creatures per frame
this massively sped up helm18
optimized monster AI a lot, merged functions, etc

Modified files:
     qc/ai.qc qc/fight.qc qc/world.qc

------=MIME.79f9c30afa7e6234c8ee365c2c102d81
Content-Type: text/plain; name="dpmod.20030220.090455.havoc.diff"
Content-Disposition: attachment; filename="dpmod.20030220.090455.havoc.diff"
Content-Transfer-Encoding: 8bit

Index: dpmod/qc/ai.qc
diff -u dpmod/qc/ai.qc:1.1.1.1 dpmod/qc/ai.qc:1.2
--- dpmod/qc/ai.qc:1.1.1.1	Thu Sep 19 15:06:58 2002
+++ dpmod/qc/ai.qc	Thu Feb 20 04:04:45 2003
@@ -260,14 +260,14 @@
 */
 float(entity targ) range =
 {
-local float             r; 
-        r = vlen ((self.origin + self.view_ofs) - (targ.origin + targ.view_ofs));
+	local float r;
+	r = vlen ((self.origin + self.view_ofs) - (targ.origin + targ.view_ofs));
 	if (r < 120)
 		return RANGE_MELEE;
 	if (r < 500)
 		return RANGE_NEAR;
-        if (r < 2000) // increased from 1000 for DP
-                return RANGE_MID;
+	if (r < 2000) // increased from 1000 for DP
+		return RANGE_MID;
 	return RANGE_FAR;
 };
 
@@ -380,8 +380,6 @@
 
 void() HuntTarget =
 {
-	if (self.health < 1)
-		return;
 	self.goalentity = self.enemy;
 	self.think = self.th_run;
 	self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
@@ -419,13 +417,14 @@
 
 float checkplayertime;
 entity lastcheckplayer;
-.float isbot;
+entity havocbot_list;
+
 
 entity() checkplayer =
 {
 	local entity check;
 	// we can just fallback on checkclient if there are no bots
-	if (!findfloat(world, isbot, TRUE))
+	if (!havocbot_list)
 		return checkclient();
 	if (time < checkplayertime)
 	{
@@ -468,16 +467,17 @@
 slower noticing monsters.
 ============
 */
+.float findtarget;
 float() FindTarget =
 {
-	local entity	client;
-	local float		r;
+	local entity client;
+	local float r;
 
 	if (self.health < 1)
 		return FALSE;
 
-	// if the first or second spawnflag bit is set, the monster will only wake
-	// up onreally seeing the player, not another monster getting angry
+	// if the first or second spawnflag bit is set, the monster will only
+	// wake up on really seeing the player, not another monster getting angry
 
 	if (self.spawnflags & 3)
 	{
@@ -511,7 +511,7 @@
 	if (client.items & IT_INVISIBILITY)
 		return FALSE;
 
-	r = range (client);
+	r = range(client);
 	if (r == RANGE_FAR)
 		return FALSE;
 
@@ -651,8 +651,9 @@
 			self.enemy = world;
 	}
 
-	if (FindTarget ())
-		return;
+	self.findtarget = TRUE;
+	//if (FindTarget ())
+	//	return;
 
 	movetogoal (dist);
 };
@@ -668,16 +669,32 @@
 void() ai_stand =
 {
 	if (self.health < 1)
-		return;
-	if (FindTarget ())
 		return;
-	
+	if (self.enemy)
+	{
+		if (self.enemy.takedamage)
+		{
+			if (self.enemy.health >= 1)
+			{
+				FoundTarget();
+				return;
+			}
+			else
+				self.enemy = world;
+		}
+		else
+			self.enemy = world;
+	}
+	self.findtarget = TRUE;
+	//if (FindTarget ())
+	//	return;
+
 	if (time > self.pausetime)
 	{
 		self.th_walk ();
 		return;
 	}
-	
+
 // change angle slightly
 
 };
@@ -691,9 +708,25 @@
 */
 void() ai_turn =
 {
-	if (FindTarget ())
-		return;
-	
+	if (self.enemy)
+	{
+		if (self.enemy.takedamage)
+		{
+			if (self.enemy.health >= 1)
+			{
+				FoundTarget();
+				return;
+			}
+			else
+				self.enemy = world;
+		}
+		else
+			self.enemy = world;
+	}
+	self.findtarget = TRUE;
+	//if (FindTarget ())
+	//	return;
+
 	ChangeYaw ();
 };
 
@@ -749,90 +782,11 @@
 //=============================================================================
 
 .float() th_checkattack;
-float() CheckAnyAttack =
-{
-	if (self.health < 1)
-		return FALSE;
-	if (!enemy_vis)
-		return FALSE;
-	return self.th_checkattack();
-};
 
 
-/*
-=============
-ai_run_melee
 
-Turn and close until within an angle to launch a melee attack
-=============
-*/
-void() ai_run_melee =
-{
-	if (self.health < 1)
-		return;
-	self.ideal_yaw = enemy_yaw;
-	ChangeYaw ();
-
-	if (FacingIdeal())
-	{
-		self.th_melee ();
-		self.attack_state = AS_STRAIGHT;
-	}
-};
-
-
 /*
 =============
-ai_run_missile
-
-Turn in place until within an angle to launch a missile attack
-=============
-*/
-void() ai_run_missile =
-{
-	if (self.health < 1)
-		return;
-	self.ideal_yaw = enemy_yaw;
-	ChangeYaw ();
-	if (FacingIdeal())
-	{
-		if (self.th_missile ())
-			self.attack_state = AS_STRAIGHT;
-	}
-};
-
-
-/*
-=============
-ai_run_slide
-
-Strafe sideways, but stay at aproximately the same range
-=============
-*/
-void() ai_run_slide =
-{
-	local float	ofs;
-	
-	if (self.health < 1)
-		return;
-	self.ideal_yaw = enemy_yaw;
-	ChangeYaw ();
-	if (self.lefty)
-		ofs = 90;
-	else
-		ofs = -90;
-	
-	if (walkmove (self.ideal_yaw + ofs, movedist))
-		return;
-		
-	self.lefty = !self.lefty;
-	
-	walkmove (self.ideal_yaw - ofs, movedist);
-};
-
-
-/*
-=============
 ai_run
 
 The monster has an enemy it is trying to kill
@@ -840,14 +794,15 @@
 */
 void(float dist) ai_run =
 {
+	local float	ofs;
 	if (self.health < 1)
 		return;
 	movedist = dist;
-// see if the enemy is dead
+	// see if the enemy is dead
 	if (self.enemy.health < 1 || self.enemy.takedamage == DAMAGE_NO)
 	{
 		self.enemy = world;
-	// FIXME: look all around for other targets
+		// FIXME: look all around for other targets
 		if (self.oldenemy.health >= 1 && self.oldenemy.takedamage)
 		{
 			self.enemy = self.oldenemy;
@@ -864,47 +819,71 @@
 		}
 	}
 
-	self.show_hostile = time + 1;		// wake up other monsters
+	// wake up other monsters
+	self.show_hostile = time + 1;
 
-// check knowledge of enemy
-	enemy_vis = visible(self.enemy);
-	if (enemy_vis)
-		self.search_time = time + 5;
-
-// look for other coop players
-	if (coop && (self.search_time < time))
-	{
-		if (FindTarget ())
-			return;
-	}
-
-	enemy_infront = infront(self.enemy);
+	// check knowledge of enemy
 	enemy_range = range(self.enemy);
-	enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
+
+	self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
+	ChangeYaw ();
 
-	if (self.attack_state == AS_MISSILE)
+	if (self.attack_state == AS_MELEE)
 	{
-//dprint ("ai_run_missile\n");
-		ai_run_missile ();
+		//dprint ("ai_run_melee\n");
+		//Turn and close until within an angle to launch a melee attack
+		if (FacingIdeal())
+		{
+			self.th_melee ();
+			self.attack_state = AS_STRAIGHT;
+		}
 		return;
 	}
-	if (self.attack_state == AS_MELEE)
+	else if (self.attack_state == AS_MISSILE)
 	{
-//dprint ("ai_run_melee\n");
-		ai_run_melee ();
+		//dprint ("ai_run_missile\n");
+		//Turn in place until within an angle to launch a missile attack
+		if (FacingIdeal())
+		if (self.th_missile ())
+			self.attack_state = AS_STRAIGHT;
 		return;
 	}
 
-	if (CheckAnyAttack ())
-		return;					// beginning an attack
-		
+	if (visible(self.enemy))
+	{
+		self.search_time = time + 5;
+		if (self.th_checkattack())
+			return;					// beginning an attack
+	}
+	else if (coop)
+	{
+		// look for other coop players
+		if (self.search_time < time)
+		{
+			self.findtarget = TRUE;
+			//if (FindTarget ())
+			//	return;
+		}
+	}
+
 	if (self.attack_state == AS_SLIDING)
 	{
-		ai_run_slide ();
-		return;
+		//dprint ("ai_run_slide\n");
+		//Strafe sideways, but stay at aproximately the same range
+		if (self.lefty)
+			ofs = 90;
+		else
+			ofs = -90;
+
+		if (walkmove (self.ideal_yaw + ofs, movedist))
+			return;
+
+		self.lefty = !self.lefty;
+
+		walkmove (self.ideal_yaw - ofs, movedist);
 	}
-		
-// head straight in
+
+	// head straight in
 	movetogoal (dist);		// done in C code...
 };
 
Index: dpmod/qc/fight.qc
diff -u dpmod/qc/fight.qc:1.1.1.1 dpmod/qc/fight.qc:1.2
--- dpmod/qc/fight.qc:1.1.1.1	Thu Sep 19 15:07:08 2002
+++ dpmod/qc/fight.qc	Thu Feb 20 04:04:45 2003
@@ -26,8 +26,7 @@
 void() ai_face;
 
 
-float	enemy_vis, enemy_infront, enemy_range;
-float	enemy_yaw;
+float enemy_range;
 
 
 //=============================================================================
Index: dpmod/qc/world.qc
diff -u dpmod/qc/world.qc:1.1.1.1 dpmod/qc/world.qc:1.2
--- dpmod/qc/world.qc:1.1.1.1	Thu Sep 19 15:08:22 2002
+++ dpmod/qc/world.qc	Thu Feb 20 04:04:45 2003
@@ -739,111 +739,129 @@
 	// 20% is normal
 };
 
+.float findtarget;
+entity creaturetocheck;
 void() startframe_creaturecode =
 {
-	local entity e;
+	local entity oldself;
 	local vector b, v, vel;
-	local float c, f, monster_count;
-	e = findfloat(world, iscreature, TRUE);
-	while (e)
+	local float c, f, monster_count, iterations;
+	oldself = self;
+	self = creaturetocheck;
+	if (self == world)
+		self = findfloat(world, iscreature, TRUE);
+	// only process up to 200 creatures per frame
+	iterations = 0;
+	while (self && iterations < 200)
 	{
-		if (e.takedamage) //e.health >= 1 || e.bodyhealth >= 1)
+		iterations = iterations + 1;
+		if (self.iscreature)
 		{
-			/*
-			if (e.bleedcount > 0)
-			if (time >= e.nextbleed)
-			if (e.velocity != '0 0 0')
+			if (self.takedamage) //self.health >= 1 || self.bodyhealth >= 1)
 			{
-				e.nextbleed = time + 0.2;
-				e.bleedcount = e.bleedcount - 5;
-				v = (e.absmin + e.absmax) * 0.5 + randomvec() * 8;
-				vel = randomvec() * 20;
-				SpawnMeatSpray(v, vel);
-			}
-			*/
-			if (e.watertype >= CONTENT_EMPTY)
-			{
-				if (e.flags & FL_INWATER)
+				if (self.findtarget)
 				{
-					// play leave water sound, but only if not an observer
-					if (e.solid)
-						sound (e, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
-					e.flags = e.flags - FL_INWATER;
+					self.findtarget = FALSE;
+					FindTarget();
 				}
-			}
-			else
-			{
-				//if (e.watertype == CONTENT_WATER || e.watertype == CONTENT_SLIME)
-				//	e.flamecount = 0;
-				if (e.movetype != MOVETYPE_NOCLIP)
-					WaterMove(e);
-			}
-			if (e.bubble_count)
-			if (time > e.bubble_time)
-			{
-				e.bubble_time = time + 0.1;
-				v = randomvec2() * 5;
-				makebubble(e.origin + '0 0 18', '0 0 15' + v, 0);
-				e.bubble_count = self.bubble_count - 1;
-				if (e.bubble_count < 1)
-					e.bubble_count = 0;
-			}
-			if (e.jump_flag < -200)
-			if (e.flags & FL_ONGROUND)
-			if (e.solid) // ignore observers
-			{
-				if (e.watertype == CONTENT_WATER)
-					sound (e, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
-				else if (e.jump_flag < -650 && world.worldtype < 3)
-				{
-					// normal quake maps
-					b = e.origin;
-					b_z = e.absmin_z;
-					//T_Damage (e, world, world, (-650 - e.jump_flag) * 0.1, (-650 - e.jump_flag) * 0.1, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
-					T_Damage (e, world, world, 5, 5, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
-					if (!e.deadflag)
-						sound (e, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
-				}
-				else if (e.jump_flag < -500 && world.worldtype >= 3)
-				{
-					// Dark Places maps
-					b = e.origin;
-					b_z = e.absmin_z;
-					T_Damage (e, world, world, (-500 - e.jump_flag) * 0.3, (-500 - e.jump_flag) * 0.3, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
-					if (!e.deadflag)
-						sound (e, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
+				/*
+				if (self.bleedcount > 0)
+				if (time >= self.nextbleed)
+				if (self.velocity != '0 0 0')
+				{
+					self.nextbleed = time + 0.2;
+					self.bleedcount = self.bleedcount - 5;
+					v = (self.absmin + self.absmax) * 0.5 + randomvec() * 8;
+					vel = randomvec() * 20;
+					SpawnMeatSpray(v, vel);
+				}
+				*/
+				if (self.watertype >= CONTENT_EMPTY)
+				{
+					if (self.flags & FL_INWATER)
+					{
+						// play leave water sound, but only if not an observer
+						if (self.solid)
+							sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
+						self.flags = self.flags - FL_INWATER;
+					}
 				}
 				else
-					sound (e, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
-			}
-			e.jump_flag = e.velocity_z;
-			/*
-			if (e.flamecount > 0)
-			{
-				e.effects = e.effects | EF_FLAME;
-				if (time > e.flametime)
+				{
+					//if (self.watertype == CONTENT_WATER || self.watertype == CONTENT_SLIME)
+					//	self.flamecount = 0;
+					if (self.movetype != MOVETYPE_NOCLIP)
+						WaterMove(self);
+				}
+				if (self.bubble_count)
+				if (time > self.bubble_time)
 				{
-					e.flametime = time + 0.1;
-					if (time > e.flamesoundtime)
+					self.bubble_time = time + 0.1;
+					v = randomvec2() * 5;
+					makebubble(self.origin + '0 0 18', '0 0 15' + v, 0);
+					self.bubble_count = self.bubble_count - 1;
+					if (self.bubble_count < 1)
+						self.bubble_count = 0;
+				}
+				if (self.jump_flag < -200)
+				if (self.flags & FL_ONGROUND)
+				if (self.solid) // ignore observers
+				{
+					if (self.watertype == CONTENT_WATER)
+						sound (self, CHAN_BODY, "player/h2ojump.wav", 1, ATTN_NORM);
+					else if (self.jump_flag < -650 && world.worldtype < 3)
 					{
-						sound (e, CHAN_AUTO, "fire/burn.wav", 1, ATTN_NORM);
-						e.flamesoundtime = time + 0.5;
+						// normal quake maps
+						b = self.origin;
+						b_z = self.absmin_z;
+						//T_Damage (self, world, world, (-650 - self.jump_flag) * 0.1, (-650 - self.jump_flag) * 0.1, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
+						T_Damage (self, world, world, 5, 5, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
+						if (!self.deadflag)
+							sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
 					}
-					f = e.flamecount;
-					if (f > 5)
-						f = 5;
-					e.flamecount = e.flamecount - f;
-					T_Damage(e, e.flameowner, e.flameowner, f, f, "FIRE", DT_FIRE, e.origin, '0 0 0', Obituary_Fire);
+					else if (self.jump_flag < -500 && world.worldtype >= 3)
+					{
+						// Dark Places maps
+						b = self.origin;
+						b_z = self.absmin_z;
+						T_Damage (self, world, world, (-500 - self.jump_flag) * 0.3, (-500 - self.jump_flag) * 0.3, " met a flat world", DT_FALL, b, '0 0 20', Obituary_Generic);
+						if (!self.deadflag)
+							sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
+					}
+					else
+						sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
+				}
+				self.jump_flag = self.velocity_z;
+				/*
+				if (self.flamecount > 0)
+				{
+					self.effects = self.effects | EF_FLAME;
+					if (time > self.flametime)
+					{
+						self.flametime = time + 0.1;
+						if (time > self.flamesoundtime)
+						{
+							sound (self, CHAN_AUTO, "fire/burn.wav", 1, ATTN_NORM);
+							self.flamesoundtime = time + 0.5;
+						}
+						f = self.flamecount;
+						if (f > 5)
+							f = 5;
+						self.flamecount = self.flamecount - f;
+						T_Damage(self, self.flameowner, self.flameowner, f, f, "FIRE", DT_FIRE, self.origin, '0 0 0', Obituary_Fire);
+					}
 				}
+				else if (self.effects & EF_FLAME)
+					self.effects = self.effects - EF_FLAME;
+				*/
 			}
-			else if (e.effects & EF_FLAME)
-				e.effects = e.effects - EF_FLAME;
-			*/
+			else
+				self.iscreature = FALSE;
 		}
-		else
-			e.iscreature = FALSE;
-		e = findfloat(e, iscreature, TRUE);
+		self = findfloat(self, iscreature, TRUE);
 	}
+	creaturetocheck = self;
+	self = oldself;
 };
 
 void() StartFrame =


More information about the twilight-commits mailing list