Today we are going to something that we haven't done in many months: improve the monster AI.
I know, that sounds weird. Some of you bot developers many think it's a travesty. But I realized that there are many Quake 1 conversions out there that could use improved creatures, and it's just so damn easy to improve them.
Indeed, I actually had fun writing this code, and I was quite amused to watch the id monsters with these changes. I think you'll enjoy it too. It sure puts id software to shame. What we will do is make the monsters run and strafe very quickly during battle.
Open up ai.qc, the monster brain file. Down at the bottom, you will find a subroutine called ai_run(). This is where the creature fights his enemy. At the end, you will see this:
if (self.attack_state == AS_SLIDING) { ai_run_slide (); return; } // head straight in movetogoal (dist); // done in C code...Nnn-kay. This movetogoal() statement makes the beast walk toward his self.goalentity. It usually zigzags, so it is slow. We want to quicken it up. So, after that, add the following:
makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_forward * 200;Those of you who have done my bot lessons will recognize this; it's my hybrid velocity method. Anyway, the makevectors() finds out what direction he is facing. The second line seperates him from the floor. And the third line will propel him forward at a speed of 200 Quake units. Looks simple, eh? Just wait until you see him dash.
/* ============= ai_face Stay facing the enemy ============= */ void() ai_face = { self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin); ChangeYaw ();After that code, paste this:
monster_run_slide();Kewl. Since ai_face() is called the most often, it is a good place to call this new monster strafing routine. Now all we have to do is write it. Before ai_face(), stick this:
// -------------------------------- void() monster_run_slide = // -------------------------------- { local float ofs; // this is a cool strafing routine if (self.lefty) ofs = 90; else ofs = -90; if (walkmove (self.ideal_yaw + ofs, 20)) { if (ofs == -90) { makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_right * 200; } else { makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_right * -200; } return; } self.lefty = 1 - self.lefty; walkmove (self.ideal_yaw - ofs, 20); if (ofs == -90) { makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_right * 200; } else { makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_right * -200; } };Okay, this is the id software routine ai_run_slide() mixed with my own velocity code. You see, whether a monster is strafing left or right is stored in self.lefty. Depending on what that value is, the float ofs is set to 90 or -90, which when subtracted from self.ideal_yaw, will make him slide left or right.