Forget about multiple attack paterns. Forget about strategic thought. Forget about navigation algorythms.
The most important aspect of bot intelligence is talking.
After all, what would a bot be if he didn't say hello, tell you about himself, insult you. Well, I guess he'd be the Tutor Bot. But that will change with this lesson.
We we learn how to give our bot an Intelligent Vocal Exposition System. That is, he'll say stuff. For this we will need two new variables, half a dozen doughnuts, an old towel, a corkscrew, and something leather.
Crack open defs.qc, where so many variables are defined. We shall introduce our new ones. Go to the very end and paste this:
.float talk_time; .float talk_subject;These variables look to be self-explantory. But briefly, when self.talk_time has elasped, the bot will say something. What he'll utter depends on self.talk_subject.
// ------------------------------------------------ void() bot_search_for_items = // ------------------------------------------------ { local entity item; // he gives up on that item and marks it to avoid it for a while if (time > self.search_time && self.goalentity != world) { self.goalentity.search_time = time + 30; self.goalentity = world; }He has just given up on finding something here. He's frustrated. Good time for him to complain. Change that if block to look like this:
if (time > self.search_time && self.goalentity != world) { self.goalentity.search_time = time + 30; self.goalentity = world; self.talk_subject = 1; self.talk_time = time + 0.1; }Uh huh. We told him to talk about subject number one during the next frame of animation. So scroll your butt on down until you see this here stuff:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void() bot_grab_items = // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { // sees if he's close enough to pick that item up if (self.goalentity == world) return; if (vlen(self.origin - self.goalentity.origin) <= 70) {Can you guess what you're going to do now? You are going to paste the following right after that:
self.talk_subject = 2; self.talk_time = time + 0.1;Okay, this is nothing that an M.I.T. grad wouldn't understand. Just kidding. It's the same idea as before. Duh!
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void() bot_walk = // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { // this is his main AI routine, where he will look for items and enemies if (!(self.flags & FL_ONGROUND)) return;Okay. this routine is his most common thought, so he will check his talk_time and call the talking code from here. So after the above, paste the below:
if (time > self.talk_time) bot_talk();Simple. In fact, this whole tutorial is so simple, I could've wrote it in Spanish and you'd still get it. Next.
self.talk_subject = 3; self.talk_time = time + 3;By now, you are an expert in this (even though it does nothing as of right now). Except, he waits three seconds before speaking. Let's go onto the last talking instance. At the very bottom of the next routine, create_bot(), where he is being born, add this:
bot.talk_subject = 4; bot.talk_time = time + 3;Whoa, check that out! Something different. Here we refer to the new entity "bot" because the self is the player creating the bot.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void() bot_talk = // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ { local float talk; if (random() < 0.5) { self.talk_subject = 0; self.talk_time = time + 60; return; } talk = floor(random() * 6); bprint(self.netname); if (self.talk_subject == 0) { if (talk == 0) bprint(": i ate my Wheaties today\n"); else if (talk == 1) bprint(": it's fun being a bot\n"); else if (talk == 2) bprint(": somebody pass the coffee\n"); else if (talk == 3) bprint(": i'm really bored\n"); else if (talk == 4) bprint(": don't call me Frog\n"); else bprint(": wish i could play CTF\n"); } if (self.talk_subject == 1) { if (talk == 0) bprint(": i hate this damn map\n"); else if (talk == 1) bprint(": this level blows\n"); else if (talk == 2) bprint(": i can't find a thing\n"); else if (talk == 3) bprint(": damn, i give up\n"); else if (talk == 4) bprint(": i feel lost\n"); else bprint(": my navigation sucks\n"); } if (self.talk_subject == 2) { if (talk == 0) bprint(": i like this level\n"); else if (talk == 1) bprint(": yeah baby yeah!\n"); else if (talk == 2) bprint(": i'm stocking up now\n"); else if (talk == 3) bprint(": i love these goodies\n"); else if (talk == 4) bprint(": i'll take this here item\n"); else bprint(": those tuts are paying off!\n"); } if (self.talk_subject == 3) { if (talk == 0) bprint(": i hate gettin fragged\n"); else if (talk == 1) bprint(": i'll get you for that\n"); else if (talk == 2) bprint(": i really stink\n"); else if (talk == 3) bprint(": i'll take my revenge soon\n"); else if (talk == 4) bprint(": don't do that again\n"); else bprint(": oh my god, you killed me!\n"); } if (self.talk_subject == 4) { if (talk == 0) bprint(": whoa this server is fast!\n"); else if (talk == 1) bprint(": hey everybody\n"); else if (talk == 2) bprint(": step aside, i'm here\n"); else if (talk == 3) bprint(": it's time to frag!\n"); else if (talk == 4) bprint(": dying time is here\n"); else bprint(": greetings everyone\n"); } sound(self, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NONE); self.talk_subject = 0; self.talk_time = time + 60; };Nice, very nice. This is an easy routine. First, the bot should not babble endlessly, so it checks a random value and perhaps leaves the routine. Then it generates a random number. It prints the bot's name. It prints a message based on his subject and the random value. It even makes that little beeping sound like when a player talks.