Probably the single most important technique in deathmatching is the circle strafe. If you can't do this, you likely suck. I suck, and I can still do this. You have to, or even bots will boot your arse.
Which means that if a bot circle strafes, he is presumably a good deathmatch opponent (witness the Reaper). Naturally, we want our bot to do this, so today we will.
(Okay, so he won't truly circle strafe; he will "square strafe." This accomplishes the same effect while being much, much simpler, and we here at the AI Cafe like simple.)
First, we will have to create a new variable to store where the bot is along the circle he will make, so he knows when to change direction. Open up defs.qc and drop to the very bottom. There, add this:
.float strafe_count;This is a simple number variable. Nothing to worry about. Call it a memory variable, if you like. Save and close that file.
// ---------------------- void() walk_forward = // ---------------------- { walkmove(self.angles_y, 20); makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_forward * self.speed; }; // ---------------------- void() walk_left = // ---------------------- { walkmove(self.angles_y + 90, 20); makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_right * self.speed * -1; }; // ---------------------- void() walk_right = // ---------------------- { walkmove(self.angles_y - 90, 20); makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_right * self.speed; }; // ---------------------- void() walk_backward = // ---------------------- { walkmove (self.angles_y - 180, 20); makevectors(self.angles); self.flags = self.flags - (self.flags & FL_ONGROUND); self.velocity = v_forward * self.speed * -1; };Note: these subroutines are to be used with the bot speed system. If you have not done that lesson, go back and do it now; it may be the single most important tutorial I've written. This circle strafe routine would probably suck without it.
// -------------------------------- void() circle_strafe = // -------------------------------- { bot_face(); if (self.strafe_count > 1 && self.strafe_count <= 1.5) walk_left(); if (self.strafe_count > 1.5 && self.strafe_count <= 2 && vlen(self.enemy.origin - self.origin) > 250) walk_forward(); if (self.strafe_count <= 0.5) walk_right(); if (self.strafe_count > 0.5 && self.strafe_count <= 1) walk_backward(); self.strafe_count = self.strafe_count + 0.1; if (self.strafe_count > 2) self.strafe_count = 0; };Uh huh. As always, this subroutine is right to the point. The bot adds 0.1 to his self.strafe_count each frame. If that count is less than or equal to 0.5, he strafes right. If the count is more than 0.5 and less than or equal to 1.0, he strafes backward. Etc, etc.
// ---------------------- void() bot_strafe = // ---------------------- {After the bracket, add the following lines ...
circle_strafe(); return;Here your bot will circle strafe, and then leave the subroutine. He will do nothing else. I leave it up to you to fine-tune this.