Better Talking

Having been playing with Coffee's TutorBot for a few days now, I've started adding my own bits and pieces to it. The first thing I did was to improve the item collection and then modify that some more. The method I used is a combination of the best parts of the first two Item Collection tutorials on Coffee's site along with the bugfixes to get it working properly. Anyone should be able to work out what I did just from that information so no more clues there.

I like my opponents to have a little personality, so I added the Talking tutorial and then noticed that something was missing - no names! I like to be taunted by the guy who killed me, I like to curse him back, with names in the text.... Seemed like a good thing to add, so here's enough to get you going.

Let's begin at the beginning. We need to declare some stuff. Open up defs.qc and move to the bottom. Insert this:


//TutorBot TALKING
//RiEvEr
// Add enemy name to taunts etc.
float TALK_BORED	=0;
float TALK_LOST	=1;
float TALK_TAUNT	=2;
float TALK_KILLED =3;
float TALK_HELLO	=4;
float TALK_MURDER =5;
float TALK_SUICIDE =6;

.string killed_by; // Who last blew this player away
.string last_killed; // Name of the last player we killed
//R

The bits in capitals are CONSTANTS. We use them to be a convenient way of getting the right number in the right place without needing to remember what the numbers mean. If I type TALK_MURDER in the code now, it will be seen as if I had typed 5 instead. It just makes things more readable and less prone to silly errors.

The two ".string" declarations will hold the names of the two players for us. The dot before the declaration means it is a member of the entity, so if we have a "self" then we now also have a "self.killed_by".

Next, open up client.qc and move down to the sub ClientObituary(), and find the bit that looks like this:


		if (attacker.classname == "teledeath2")
		{
			bprint ("Satan's power deflects ");
			bprint (targ.netname);
			bprint ("'s telefrag\n");

			targ.frags = targ.frags - 1;
			return;
		}

		if (attacker.classname == "player" || attacker.classname == "bot")//TutorBot
		{

and right after it add this:

//TutorBot TALKING RiEvEr
			targ.killed_by = attacker.netname;
			attacker.last_killed = targ.netname;
//TB T R

This saves a copy of the names of the two combatants involved in the incident that caused the death of "targ" at the hands of "attacker". Next, slip down a bit in the same subroutine until you see this:


				if (rnum == IT_LIGHTNING)
				{
					deathstring = " accepts ";
					if (attacker.waterlevel > 1)
						deathstring2 = "'s discharge\n";
					else
						deathstring2 = "'s shaft\n";
				}
				bprint (targ.netname);
				bprint (deathstring);
				bprint (attacker.netname);
				bprint (deathstring2);

and then immediately add this:

//TutorBot TALKING RiEvEr
				attacker.talk_subject = TALK_MURDER;
				attacker.talk_time = time + 0.5;
//TB T R

See? That was simple. You can save and close that file. Next, we want to open tutor.qc and go to the sub bot_talk(), find this section:

	if (self.talk_subject == 4)
		{
		if (talk == 0) bprint(": whoa this server is fast...NOT!\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 die!\n");
		else if (talk == 4) bprint(": dying time is here\n");
		else bprint(": Hey, anybody seen RiEvEr?\n");
		}

and right after it add this:

//TutorBot TALKING RiEvEr
	if (self.talk_subject == TALK_MURDER)
		{
		if (talk == 0){	 bprint(": Gee, ");bprint(self.last_killed);bprint(", your mom must be so proud...\n");}
		else if (talk == 1){	bprint(": ");bprint(self.last_killed);bprint(", you really need ta get out more.\n");}
		else if (talk == 2){	bprint(": hey watch it, ");bprint(self.last_killed);bprint(" you nearly bled on my shoe!\n");}
		else if (talk == 3){	bprint(": it's always the same, ");bprint(self.last_killed);bprint(", one guy wins, the other schmuck loses.\n");}
		else if (talk == 4){	 bprint(": ");bprint(self.last_killed);bprint(", was that you?\n");}
		else{	 bprint(": oh my god,  I killed ");bprint(self.last_killed);bprint("!\n");}
		}
//TB T R

And that's it! Just make sure you save and close those files and compile them. Now play, and be insulted.

If you've been paying attention, you'll notice that the facility exists to add names to the speech that the bot makes when it respawns after death (TALK_KILLED). You just need to use self.killed_by. Go away, improve it, have fun...


What We Learned

1. The bot can store information about players
2. It's easy to insult people by name.
3. There are often simple solutions to seemingly tricky problems
4. There is no number four.

 


Author: RiEvEr
Questions: riever@planetquake.com
AI chat on ICQ: 25649000