Name of Mod        : Bot Frame
File Name          : botframe.zip
Version            : N/A
Date               : August 10, 1999
E-mail             : thefatal@telefragged.com
Web Site           : http://www.telefragged.com/thefatal/
---------------------------------------------------------
This is for people wanting to make their own Half-Life bot.
Before you start you will need the standard/pro SDK for
Half-Life, and a compiler capable of compiling it (such as
Microsoft Visual C++ 5.0 or later).

The following files are included with the archive:

basemonster.h
bot.cpp
client.cpp

To compile the code properly, copy client.cpp and basemonster.h into your
folder containing the SDK code over the original copies, and copy bot.cpp
into the same folder. Now, open the project and add bot.cpp to it. Compile
it and you'll have a fully working mp.dll. Put the liblist.gam file
included in the archive in a folder under your Half-Life directory called
"bot", then created a folder called "dlls" under the bot folder and put
the mp.dll file in that. Start HL, select the bot with the custom game
option, start a LAN game, type "addbot" in the console once you've
loaded up a map, and you can see the inactive bot that you've spawned.
Now, onto explaining the source code bit by bit.

Note that all modifications to basemonster.h and client.cpp are marked
by "START BOT" and "END BOT". bot.cpp is written from scratch, so it
is not marked. Also note that these basemonster.h and client.cpp files
are from the standard SDK and not the pro SDK, so if you have the pro
SDK you may want to insert the changes in the files manually instead
of copying them over the pro SDK files. The pro SDK files are different
in other ways and may cause compilation errors if you copy the standard
SDK files over them.

First, let's open basemonster.h. Skip down to line 39, and you'll see:

	virtual int	 BloodColor( void ) { return m_bloodColor; }
	//The above line is only needed if you are using the standard SDK and
	//not the pro SDK.
	int isabot;
	virtual void BThink ( void );

The BloodColor virtual function only needs to be added if you don't have
the pro SDK. It causes the bots and other players to "bleed", which was
originally taken out of the standard SDK.
The isabot value is used to store if a client is a bot or player. We'll
set it to 1 for bots, and leave it at 0 for players.
The BThink virtual function will be our function which acts as the bot's
think function and is called for it each frame.

Now, let's open client.cpp. Move down to line 317, and you'll see:

	void BotConnect( edict_t *aEntity);

This just predeclares the bot connection function (in bot.cpp) so that
it can be called later in another function. Now, skip to line 376.

	else if (FStrEq(pcmd, "addbot" ))
	{
		BotConnect(pEntity); //If user types "addbot" in console, add a bot.
	}

This checks to see if the "addbot" command has been entered by a client,
and if it has, it calls our bot connection function in bot.cpp. Now onto
line 508.

CBasePlayer	*CBasePlayerByIndex( int playerIndex )
{
	CBasePlayer *pPlayer = NULL;
	entvars_t *pev;

	if ( playerIndex > 0 && playerIndex <= gpGlobals->maxClients )
	{
		edict_t *pPlayerEdict = INDEXENT( playerIndex );
		if ( pPlayerEdict && !pPlayerEdict->free && (pPlayerEdict->v.flags & FL_FAKECLIENT || pPlayerEdict->v.flags & FL_CLIENT) ) //fake
		{
			pev = &pPlayerEdict->v;
			pPlayer = GetClassPtr((CBasePlayer *)pev);
		}
	}
	
	return pPlayer;
}

This function finds a player given his index number and returns him to us.
This function is used directly below down on line 530.

	for ( int i = 1; i <= gpGlobals->maxClients; i++ )
	{
		CBasePlayer *pPlayer = CBasePlayerByIndex( i );

		if (pPlayer && pPlayer->isabot == 1) {
			pPlayer->BThink(); //Find a bot each frame and call its think function.
		}
	}

This is under the StartFrame function so that it is called once every
frame. It cycles through all clients in the game, and if it finds one
that is a bot, it calls the bot think function for it. Well, that's
all for client.cpp, so, finally, go and open up bot.cpp.

In bot.cpp, we first define the CBot class so we can set the isnetclient
value to false for bots as it should be.

Next, we define the bot think function. You'll need to put your own AI
here. Currently it just calls the player physics function. The comment
below the call to pfnRunPlayerMove (the physics function) shows you what
each of the values in the call to the function are for.

The following functions are fairly self-explanitory. They create a fake
client edict using pfnCreateFakeClient and connect the bot to the server
by attaching it to a player object.

Well then, that should be all you need to get started on your own bot.
Good luck.

COPYRIGHT/PERMISSIONS
---------------------
You may do whatever you want with this code, as long as you give me
some credit for it.
