Well, as far as his answer to #2...
bot.h file...
Code:
//=============================================================================//
//
// bot.h - bot header file (Copyright 2004, Jeffrey "botman" Broome)
//
//=============================================================================//
#ifndef BOT_H
#define BOT_H
typedef struct
{
CSDKPlayer* pPlayer;
} bot_t;
#endif // BOT_H
bot.cpp file...
Code:
//=============================================================================//
//
// bot.cpp - bot source code file (Copyright 2004, Jeffrey "botman" Broome)
//
//=============================================================================//
#include "cbase.h"
#include "entitylist.h"
#include "mapentities_shared.h"
//#include "isaverestore.h"
//#include "eventqueue.h"
//#include "entityinput.h"
//#include "entityoutput.h"
//#include "mempool.h"
//#include "vstdlib/strtools.h"
//#include "engine/IVEngineCache.h"
//#include "tier0/vprof.h"
#include "client.h"
#include "sdk_player.h"
#include "movehelper_server.h"
#include "in_buttons.h"
#include "bot.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// private data for each bot
static bot_t gBots[32];
void BotThink(CSDKPlayer* pBot);
CSDKPlayer* CreateBot(const char* name)
{
edict_t *pEdict = engine->CreateFakeClient( name );
if (!pEdict)
{
Msg("CreateBot: ERROR - Counldn't create a bot!!!\n");
return NULL;
}
// ClientPutInServer(pEdict, name); // you don't need this for bots in Source
CSDKPlayer *pPlayer = ((CSDKPlayer *)CBaseEntity::Instance( pEdict ));
pPlayer->ClearFlags();
pPlayer->AddFlag( FL_CLIENT | FL_FAKECLIENT );
bot_t *pBot = &gBots[ engine->IndexOfEdict(pEdict) - 1 ];
// initialize any private bot data here...
pBot->pPlayer = pPlayer;
Msg("CreateBot: bot was added successfully to server\n");
return pPlayer;
}
void AddBot( void )
{
Msg("AddBot: Adding a bot...\n");
CreateBot("Player"); // create a bot named "Player"
}
ConCommand addbot( "addbot", AddBot, "add a bot to the game." );
// called by GameStartFrame() at the start of every frame, let's the bots Think...
void BotStartFrame(void)
{
for ( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CSDKPlayer *pPlayer = ToSDKPlayer( UTIL_PlayerByIndex( i ) );
if ((pPlayer != NULL) && (pPlayer->GetFlags() & FL_FAKECLIENT))
{
BotThink( pPlayer );
}
}
}
// see CBasePlayer::RunNullCommand() for example of PlayerRunCommand()...
void BotRunPlayerMove(CSDKPlayer* pPlayer)
{
CUserCmd cmd;
// Store off the globals.. they're gonna get whacked
float flOldFrametime = gpGlobals->frametime;
float flOldCurtime = gpGlobals->curtime;
pPlayer->pl.fixangle = FIXANGLE_NONE;
cmd.viewangles = pPlayer->EyeAngles();
float flTimeBase = gpGlobals->curtime;
pPlayer->SetTimeBase( flTimeBase );
cmd.forwardmove = 200.0f;
cmd.sidemove = 0;
cmd.upmove = 0;
cmd.buttons = IN_JUMP;
cmd.impulse = 0;
if ( pPlayer->IsDead() ) // respawn dead players
{
if (RandomInt(0,1))
cmd.buttons = 0;
else
cmd.buttons = IN_ATTACK;
}
MoveHelperServer()->SetHost( pPlayer );
pPlayer->PlayerRunCommand( &cmd, MoveHelperServer() );
// save off the last good usercmd
pPlayer->SetLastUserCommand( cmd );
// Restore the globals..
gpGlobals->frametime = flOldFrametime;
gpGlobals->curtime = flOldCurtime;
}
void BotThink(CSDKPlayer* pPlayer)
{
bot_t *pBot = &gBots[ engine->IndexOfEdict(pPlayer->edict()) - 1 ];
pPlayer->AddFlag( FL_FAKECLIENT ); // make sure this is set every frame
BotRunPlayerMove(pPlayer);
}
You can just drop those 2 files into the 'dlls' folder of your Half-Life2 MOD (mine's called "MyMod"), so it would be MyMod\src\dlls\bot.h and MyMod\src\dlls\bot.cpp. Add bot.cpp to the list of source files in the Solution Explorer, build the DLLs and you can spawn a bot using "addbot" in the console.
EDIT: Opps, you also have to add...
void BotStartFrame(void);
...after line 38 of sdk_client.cpp in the dlls\sdk folder and add this...
BotStartFrame();
...at the very end of the "void GameStartFrame( void )" function in that same file (sdk_client.cpp).
botman