Inside3D tutorials.
Created By: Pob the Impaler (Paul Johnstone)
eMail: itac025@lauder.ac.uk
Difficulty Scale: Medium




Yipee the RIPs are back...

Legion (Roscoe Sincero) has buggered off to work on his ElimaReaper patch, so I'll be filling his shoes for a while.
He is still active in a consultancy capacity, so I can still draw on his wealth of knowledge for support.

So, my name is Pob the Impaler (Paul Johnstone), you can send me mail at:
A.W.Johnstone@btinternet.com (for home)
OR
itac025@lauder.ac.uk (for College)
I don't mind which address you use, so when I inevitably make a boo-boo you'll know how to send me
hate-mail :)
My site is at: http://www.btinternet.com/~impaler please help my hit-counter and visit!

Roscoe Sincero's address is legion@keg.zymurgy.org

//------------//
//-Credits--//
//-----------//

Steve Polge - For the Reaper bots
Alan Kivlin - For the clever scoreboard stuff
Lee Smith - For ProQCC
Roscoe Sincero - For starting it all off and for giving me a shot of his ElimaReaper!


----My Mission------------
My aim is to make the bot's at least aesthetically indistinguishable from human opponents.
So eventually there will be a facility for random bot skills in Teamplay (incase you haven't noticed
teamplay games are stacked HEAVILY in favour of your team).
We will also lose the "The_Mastermind (skill 3) entered the game" and replace with "The_Mastermin entered the game".
This lesson is a step in the right direction....


|=========================================================|

ALWAYS MAKE A BACKUP OF YOUR CODE BEFORE TRYING ONE OF MY LESSONS. IF THERE IS A MISTAKE IN IT WHICH RUINS YOUR CODE OR BLOWS UP YOUR HOUSE, TOUGH SHIT, RESTORE THE BACKUP AND TELL ME WHERE I FUCKED UP.

I got really bored today, so I made this!
Come on kids - let's get those bots chatting!

Basic Premise...
We want the bots to speak.
We want about 20 phrases like "You're dead you muddy funster!"
We want to use name in the phrases "Hey Fidgit check the safety catch!"
Some of them must be useful..... :)
We don't want the normal message beep, cos it's annoying.

OK KIDS.. LET'S ROCK :)


Step 1


Bot_ai.qc


All of this is done in Bot_ai.qc so open it up and find the function runaway  float () RunAway = {

At the top add:
//---Begin Code---//
local float runawayspeakchance;
runawayspeakchance = random();  // this is the chance that a bot will speak
//---End Code---//

Now find: 
if ( (self.enemy.items & IT_INVULNERABILITY) ) {

beneath this line add:

//---Begin Code---//
if (runawayspeakchance <= 0.1)
{
bprint(self.netname);
bprint(": Run for it, ");
bprint(self.enemy.netname);
bprint(" has a pentagram of protection!\n");
}
//---End Code---//

Now find:
if ( (self.health < 45.000) ) {

under this line add:

//---Begin Code---//
if (runawayspeakchance <= 0.001)
{
bprint(self.netname);
bprint(": I'm low on health!\n");
}
if ((runawayspeakchance <= 0.002) && (runawayspeakchance > 0.001))
{
bprint(self.netname);
bprint(": Run Away!\n");
}
//---End Code---//

Now find:
 if ( (self.enemy.items & IT_QUAD) ) {

under this line add:

//---Begin Code---//
if (runawayspeakchance <= 0.1)
{
bprint(self.netname);
bprint(": Run for it, ");
bprint(self.enemy.netname);
bprint(" has Quad Damage!\n");
}

//---End Code---//

Now find:
if ( (self.enemy.weapon & ((IT_ROCKET_LAUNCHER + IT_LIGHTNING) + IT_SUPER_NAILGUN)) ) {

under this line add:

//---Begin Code---//
if (runawayspeakchance <= 0.1)
{
bprint(self.netname);
bprint(": Run for it, ");
bprint(self.enemy.netname);
bprint(" is totally tooled up!\n");
}
//---End Code---//

Now find:
if ( (self.health < 70.000) ) {

under this line add:

//---Begin Code---//
if (runawayspeakchance <= 0.1)
{
bprint(self.netname);
bprint(": I'm being mobbed!");
}
//---End Code---//




Step 2

Find the function Bot FoundTarget  float () BotFoundTarget = {

At the top add this: (you'd be quicker using cut & paste here)

//---Begin Code---//
local float huntspeakchance;
huntspeakchance = random();
//---End Code---//

Now find:

BotHuntTarget ();

under this line add:

//---Begin Code---//
if (huntspeakchance <= 0.01)
{
bprint(self.netname);
bprint(": I'm gonna rip your heart out ");
bprint(self.enemy.netname);
bprint("!\n");
}
if ((huntspeakchance <= 0.02) && (huntspeakchance > 0.01))
{
bprint(self.netname);
bprint(": This is gonna hurt you so much ");
bprint(self.enemy.netname);
bprint("!\n");
}
if ((huntspeakchance <= 0.03) && (huntspeakchance > 0.02))
{
bprint(self.netname);
bprint(": I can see you ");
bprint(self.enemy.netname);
bprint("!\n");
}
if ((huntspeakchance <= 0.04) && (huntspeakchance > 0.03))
{
bprint(self.netname);
bprint(": You are so dead ");
bprint(self.enemy.netname);
bprint("!\n");
}
if ((huntspeakchance <= 0.05) && (huntspeakchance > 0.04))
{
bprint(self.netname);
bprint(": ");
bprint(self.enemy.netname);
bprint(" is going to die in about 10 seconds");
bprint("!\n");
}
if ((huntspeakchance <= 0.006) && (huntspeakchance > 0.005))
{
bprint(self.netname);
bprint(": ");
bprint(self.enemy.netname);
bprint(" has 5 seconds to live");
bprint("!\n");
}
if ((huntspeakchance <= 0.007) && (huntspeakchance > 0.006))
{
bprint(self.netname);
bprint(": This ain't no party, it's a freakin' GIB-FEST!\n");
}
if ((huntspeakchance <= 0.008) && (huntspeakchance > 0.007))
{
bprint(self.netname);
bprint(": Come on you Gib-Meat newbies, I'll frag you all!\n");
}
if ((huntspeakchance <= 0.009) && (huntspeakchance > 0.008))
{
bprint(self.netname);
bprint(": Try taking the safety off ");
bprint(self.enemy.netname);
bprint(" HA HA!\n");
}
if ((huntspeakchance <= 0.010) && (huntspeakchance > 0.009))
{
bprint(self.netname);
bprint(": GIB GIB GIB GIB BLOOD GIB GIB SPOOGE!\n");
}
if ((huntspeakchance <= 0.011) && (huntspeakchance > 0.010))
{
bprint(self.netname);
bprint(": What's the matter ");
bprint(self.enemy.netname);
bprint("? Has you're gun jammed?\n");
}

//---End Code---//

Now save and compile!


Step 3

Actually we might as well put CallForHelp in while we're at it....

Step 3.

Open bot_ai.qc again
Find the function CallForHelp  void () CallForHelp = {

Make it look like this (sorry I can't just say what lines to change, 'cos a lot has changed in it!)
(You would probably be safer just using copy & paste for this..)

//---Begin Code---//
void () CallForHelp = {

   local entity e;
   local entity p;
   local entity tmp;
   local float d;
local entity protect;   // protect is the beastie that the player needs protecting from.
   HELPING = TRUE;
if (self.classname == "player")
{
sprint(self,self.netname);
sprint(self,": Help Me!\n");
}


   e = find (world,classname,"dmbot");
   while ( e ) {
      if ( (e != self) ) {
         if ( (e.team == self.team) || (coop == 1) ) {


           

               if ( (e.health > 80.000) ) {



                     p = BestChaseRoute (e,self.enemy);
                     traceline (e.origin,self.enemy.origin,TRUE,e);
                     if ( ((trace_fraction == TRUE) || (p.enemycache == self.enemy)) ) {


                                                   
                       
                        e.enemy = self.enemy;
if (self.classname == "player")
{

protect = findradius(self.origin,8000);
        while (protect)
        {
if ((protect.enemy.classname == "player") && (protect.flags & FL_MONSTER)) // protect agains monsters
{
e.enemy = protect;
p = BestChaseRoute (e,e.enemy);
sprint (self,e.teamname);
sprint (self,e.netname);
sprint (self,": I'm coming to help you nail that ");
sprint(self,e.enemy.classname);
sprint(self,"\n");

}

if ((protect.enemy == self) && (protect.classname == "dmbot")) // protect against enemy bots
{

e.enemy = protect;
p = BestChaseRoute (e,e.enemy);
sprint (self,e.teamname);
sprint (self,e.netname);
sprint (self,": I'm coming to help you nail ");
sprint(self,e.enemy.netname);
sprint(self,"\n");

}

        protect = protect.chain;

        }

}


                                tmp = self;
                        self = e;
                        BotFoundTarget ();
                        if ( (self.goalentity.classname != "BotTarget") ) {

                           objerror ("bad bot target in bot_ai! 1\n");

                        }
                        setorigin (self.goalentity,p.origin);
                        self = tmp;

                     }

                  }

         }

      }
      e = find (e,classname,"dmbot");

   }
   HELPING = FALSE;

};
//---End Code---//

Now save and open bot_imp.qc
Find the function botRestrictedCommand  void () botRestrictedCommand = {

Find the line:
 if ( (self.impulse == 217.000) ) {

delete the lines:

                                        tmp = ftos (NUMPATHS);
                                dprint (tmp);
                                dprint (" botpaths placed\n");

now add:

//---Begin Code---//
CallForHelp()
//---End Code---//

Underneath this line there should be a line which reads:

DropBotPath();

If it isn't there, then add it.

Ok now save and compile.

In the game, bind a key (like "h") to impulse 217
You will now be able to call for help if you are under attack from enemy teambots or monsters!!

|=========================================================|

Well that's it folks!

see 'ya next time!