Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

g_bot.c File Reference

#include "g_local.h"

Include dependency graph for g_bot.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  botSpawnQueue_t

Defines

#define BOT_BEGIN_DELAY_BASE   2000
#define BOT_BEGIN_DELAY_INCREMENT   1500
#define BOT_SPAWN_QUEUE_DEPTH   16

Functions

void AddBotToSpawnQueue (int clientNum, int delay)
void G_AddBot (const char *name, float skill, const char *team, int delay, char *altname)
void G_AddRandomBot (int team)
qboolean G_BotConnect (int clientNum, qboolean restart)
void G_CheckBotSpawn (void)
void G_CheckMinimumPlayers (void)
int G_CountBotPlayers (int team)
int G_CountHumanPlayers (int team)
const char * G_GetArenaInfoByMap (const char *map)
char * G_GetBotInfoByName (const char *name)
char * G_GetBotInfoByNumber (int num)
void G_InitBots (qboolean restart)
void G_LoadArenas (void)
void G_LoadArenasFromFile (char *filename)
void G_LoadBots (void)
void G_LoadBotsFromFile (char *filename)
int G_ParseInfos (char *buf, int max, char *infos[])
void G_RemoveQueuedBotBegin (int clientNum)
int G_RemoveRandomBot (int team)
void G_SpawnBots (char *botList, int baseDelay)
void PlayerIntroSound (const char *modelAndSkin)
void Svcmd_AddBot_f (void)
void Svcmd_BotList_f (void)
float trap_Cvar_VariableValue (const char *var_name)

Variables

vmCvar_t bot_minplayers
botSpawnQueue_t botSpawnQueue [BOT_SPAWN_QUEUE_DEPTH]
char * g_arenaInfos [MAX_ARENAS]
char * g_botInfos [MAX_BOTS]
int g_numArenas
int g_numBots
gentity_tpodium1
gentity_tpodium2
gentity_tpodium3


Define Documentation

#define BOT_BEGIN_DELAY_BASE   2000
 

Definition at line 36 of file g_bot.c.

#define BOT_BEGIN_DELAY_INCREMENT   1500
 

Definition at line 37 of file g_bot.c.

#define BOT_SPAWN_QUEUE_DEPTH   16
 

Definition at line 39 of file g_bot.c.


Function Documentation

void AddBotToSpawnQueue int  clientNum,
int  delay
[static]
 

Definition at line 501 of file g_bot.c.

References botSpawnQueue, ClientBegin(), botSpawnQueue_t::clientNum, G_Printf(), level, n, S_COLOR_YELLOW, botSpawnQueue_t::spawnTime, and level_locals_t::time.

Referenced by G_AddBot().

00501                                                            {
00502     int     n;
00503 
00504     for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00505         if( !botSpawnQueue[n].spawnTime ) {
00506             botSpawnQueue[n].spawnTime = level.time + delay;
00507             botSpawnQueue[n].clientNum = clientNum;
00508             return;
00509         }
00510     }
00511 
00512     G_Printf( S_COLOR_YELLOW "Unable to delay spawn\n" );
00513     ClientBegin( clientNum );
00514 }

Here is the call graph for this function:

void G_AddBot const char *  name,
float  skill,
const char *  team,
int  delay,
char *  altname
[static]
 

Definition at line 566 of file g_bot.c.

References AddBotToSpawnQueue(), ClientBegin(), ClientConnect(), g_entities, g_gametype, G_GetBotInfoByName(), G_Printf(), gentity_t, Info_SetValueForKey(), Info_ValueForKey(), gentity_s::inuse, name, PickTeam(), qtrue, gentity_s::r, s, S_COLOR_RED, entityShared_t::svFlags, trap_BotAllocateClient(), trap_Printf(), trap_SetUserinfo(), and va().

Referenced by Svcmd_AddBot_f().

00566                                                                                                  {
00567     int             clientNum;
00568     char            *botinfo;
00569     gentity_t       *bot;
00570     char            *key;
00571     char            *s;
00572     char            *botname;
00573     char            *model;
00574     char            *headmodel;
00575     char            userinfo[MAX_INFO_STRING];
00576 
00577     // get the botinfo from bots.txt
00578     botinfo = G_GetBotInfoByName( name );
00579     if ( !botinfo ) {
00580         G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
00581         return;
00582     }
00583 
00584     // create the bot's userinfo
00585     userinfo[0] = '\0';
00586 
00587     botname = Info_ValueForKey( botinfo, "funname" );
00588     if( !botname[0] ) {
00589         botname = Info_ValueForKey( botinfo, "name" );
00590     }
00591     // check for an alternative name
00592     if (altname && altname[0]) {
00593         botname = altname;
00594     }
00595     Info_SetValueForKey( userinfo, "name", botname );
00596     Info_SetValueForKey( userinfo, "rate", "25000" );
00597     Info_SetValueForKey( userinfo, "snaps", "20" );
00598     Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );
00599 
00600     if ( skill >= 1 && skill < 2 ) {
00601         Info_SetValueForKey( userinfo, "handicap", "50" );
00602     }
00603     else if ( skill >= 2 && skill < 3 ) {
00604         Info_SetValueForKey( userinfo, "handicap", "70" );
00605     }
00606     else if ( skill >= 3 && skill < 4 ) {
00607         Info_SetValueForKey( userinfo, "handicap", "90" );
00608     }
00609 
00610     key = "model";
00611     model = Info_ValueForKey( botinfo, key );
00612     if ( !*model ) {
00613         model = "visor/default";
00614     }
00615     Info_SetValueForKey( userinfo, key, model );
00616     key = "team_model";
00617     Info_SetValueForKey( userinfo, key, model );
00618 
00619     key = "headmodel";
00620     headmodel = Info_ValueForKey( botinfo, key );
00621     if ( !*headmodel ) {
00622         headmodel = model;
00623     }
00624     Info_SetValueForKey( userinfo, key, headmodel );
00625     key = "team_headmodel";
00626     Info_SetValueForKey( userinfo, key, headmodel );
00627 
00628     key = "gender";
00629     s = Info_ValueForKey( botinfo, key );
00630     if ( !*s ) {
00631         s = "male";
00632     }
00633     Info_SetValueForKey( userinfo, "sex", s );
00634 
00635     key = "color1";
00636     s = Info_ValueForKey( botinfo, key );
00637     if ( !*s ) {
00638         s = "4";
00639     }
00640     Info_SetValueForKey( userinfo, key, s );
00641 
00642     key = "color2";
00643     s = Info_ValueForKey( botinfo, key );
00644     if ( !*s ) {
00645         s = "5";
00646     }
00647     Info_SetValueForKey( userinfo, key, s );
00648 
00649     s = Info_ValueForKey(botinfo, "aifile");
00650     if (!*s ) {
00651         trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" );
00652         return;
00653     }
00654 
00655     // have the server allocate a client slot
00656     clientNum = trap_BotAllocateClient();
00657     if ( clientNum == -1 ) {
00658         G_Printf( S_COLOR_RED "Unable to add bot.  All player slots are in use.\n" );
00659         G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" );
00660         return;
00661     }
00662 
00663     // initialize the bot settings
00664     if( !team || !*team ) {
00665         if( g_gametype.integer >= GT_TEAM ) {
00666             if( PickTeam(clientNum) == TEAM_RED) {
00667                 team = "red";
00668             }
00669             else {
00670                 team = "blue";
00671             }
00672         }
00673         else {
00674             team = "red";
00675         }
00676     }
00677     Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) );
00678     Info_SetValueForKey( userinfo, "skill", va( "%5.2f", skill ) );
00679     Info_SetValueForKey( userinfo, "team", team );
00680 
00681     bot = &g_entities[ clientNum ];
00682     bot->r.svFlags |= SVF_BOT;
00683     bot->inuse = qtrue;
00684 
00685     // register the userinfo
00686     trap_SetUserinfo( clientNum, userinfo );
00687 
00688     // have it connect to the game as a normal client
00689     if ( ClientConnect( clientNum, qtrue, qtrue ) ) {
00690         return;
00691     }
00692 
00693     if( delay == 0 ) {
00694         ClientBegin( clientNum );
00695         return;
00696     }
00697 
00698     AddBotToSpawnQueue( clientNum, delay );
00699 }

Here is the call graph for this function:

void G_AddRandomBot int  team  ) 
 

Definition at line 237 of file g_bot.c.

References cl, level_locals_t::clients, EXEC_INSERT, g_botInfos, g_entities, g_maxclients, gclient_t, i, Info_ValueForKey(), vmCvar_t::integer, level, n, Q_CleanStr(), Q_stricmp(), gentity_s::r, random, strncpy(), entityShared_t::svFlags, trap_Cvar_VariableValue(), trap_SendConsoleCommand(), va(), and value.

Referenced by G_CheckMinimumPlayers().

00237                                 {
00238     int     i, n, num;
00239     float   skill;
00240     char    *value, netname[36], *teamstr;
00241     gclient_t   *cl;
00242 
00243     num = 0;
00244     for ( n = 0; n < g_numBots ; n++ ) {
00245         value = Info_ValueForKey( g_botInfos[n], "name" );
00246         //
00247         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00248             cl = level.clients + i;
00249             if ( cl->pers.connected != CON_CONNECTED ) {
00250                 continue;
00251             }
00252             if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00253                 continue;
00254             }
00255             if ( team >= 0 && cl->sess.sessionTeam != team ) {
00256                 continue;
00257             }
00258             if ( !Q_stricmp( value, cl->pers.netname ) ) {
00259                 break;
00260             }
00261         }
00262         if (i >= g_maxclients.integer) {
00263             num++;
00264         }
00265     }
00266     num = random() * num;
00267     for ( n = 0; n < g_numBots ; n++ ) {
00268         value = Info_ValueForKey( g_botInfos[n], "name" );
00269         //
00270         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00271             cl = level.clients + i;
00272             if ( cl->pers.connected != CON_CONNECTED ) {
00273                 continue;
00274             }
00275             if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00276                 continue;
00277             }
00278             if ( team >= 0 && cl->sess.sessionTeam != team ) {
00279                 continue;
00280             }
00281             if ( !Q_stricmp( value, cl->pers.netname ) ) {
00282                 break;
00283             }
00284         }
00285         if (i >= g_maxclients.integer) {
00286             num--;
00287             if (num <= 0) {
00288                 skill = trap_Cvar_VariableValue( "g_spSkill" );
00289                 if (team == TEAM_RED) teamstr = "red";
00290                 else if (team == TEAM_BLUE) teamstr = "blue";
00291                 else teamstr = "";
00292                 strncpy(netname, value, sizeof(netname)-1);
00293                 netname[sizeof(netname)-1] = '\0';
00294                 Q_CleanStr(netname);
00295                 trap_SendConsoleCommand( EXEC_INSERT, va("addbot %s %f %s %i\n", netname, skill, teamstr, 0) );
00296                 return;
00297             }
00298         }
00299     }
00300 }

Here is the call graph for this function:

qboolean G_BotConnect int  clientNum,
qboolean  restart
 

Definition at line 542 of file g_bot.c.

References atof(), bot_settings_t, BotAISetupClient(), bot_settings_s::characterfile, Info_ValueForKey(), Q_strncpyz(), qboolean, bot_settings_s::skill, bot_settings_s::team, trap_DropClient(), and trap_GetUserinfo().

Referenced by ClientConnect().

00542                                                          {
00543     bot_settings_t  settings;
00544     char            userinfo[MAX_INFO_STRING];
00545 
00546     trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
00547 
00548     Q_strncpyz( settings.characterfile, Info_ValueForKey( userinfo, "characterfile" ), sizeof(settings.characterfile) );
00549     settings.skill = atof( Info_ValueForKey( userinfo, "skill" ) );
00550     Q_strncpyz( settings.team, Info_ValueForKey( userinfo, "team" ), sizeof(settings.team) );
00551 
00552     if (!BotAISetupClient( clientNum, &settings, restart )) {
00553         trap_DropClient( clientNum, "BotAISetupClient failed" );
00554         return qfalse;
00555     }
00556 
00557     return qtrue;
00558 }

Here is the call graph for this function:

void G_CheckBotSpawn void   ) 
 

Definition at line 472 of file g_bot.c.

References botSpawnQueue, ClientBegin(), G_CheckMinimumPlayers(), g_gametype, Info_ValueForKey(), level, n, PlayerIntroSound(), botSpawnQueue_t::spawnTime, level_locals_t::time, and trap_GetUserinfo().

Referenced by BotAIStartFrame().

00472                              {
00473     int     n;
00474     char    userinfo[MAX_INFO_VALUE];
00475 
00476     G_CheckMinimumPlayers();
00477 
00478     for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00479         if( !botSpawnQueue[n].spawnTime ) {
00480             continue;
00481         }
00482         if ( botSpawnQueue[n].spawnTime > level.time ) {
00483             continue;
00484         }
00485         ClientBegin( botSpawnQueue[n].clientNum );
00486         botSpawnQueue[n].spawnTime = 0;
00487 
00488         if( g_gametype.integer == GT_SINGLE_PLAYER ) {
00489             trap_GetUserinfo( botSpawnQueue[n].clientNum, userinfo, sizeof(userinfo) );
00490             PlayerIntroSound( Info_ValueForKey (userinfo, "model") );
00491         }
00492     }
00493 }

Here is the call graph for this function:

void G_CheckMinimumPlayers void   ) 
 

Definition at line 397 of file g_bot.c.

References bot_minplayers, G_AddRandomBot(), G_CountBotPlayers(), G_CountHumanPlayers(), g_gametype, g_maxclients, G_RemoveRandomBot(), vmCvar_t::integer, level_locals_t::intermissiontime, level, TEAM_BLUE, TEAM_FREE, TEAM_RED, TEAM_SPECTATOR, level_locals_t::time, and trap_Cvar_Update().

Referenced by G_CheckBotSpawn().

00397                                    {
00398     int minplayers;
00399     int humanplayers, botplayers;
00400     static int checkminimumplayers_time;
00401 
00402     if (level.intermissiontime) return;
00403     //only check once each 10 seconds
00404     if (checkminimumplayers_time > level.time - 10000) {
00405         return;
00406     }
00407     checkminimumplayers_time = level.time;
00408     trap_Cvar_Update(&bot_minplayers);
00409     minplayers = bot_minplayers.integer;
00410     if (minplayers <= 0) return;
00411 
00412     if (g_gametype.integer >= GT_TEAM) {
00413         if (minplayers >= g_maxclients.integer / 2) {
00414             minplayers = (g_maxclients.integer / 2) -1;
00415         }
00416 
00417         humanplayers = G_CountHumanPlayers( TEAM_RED );
00418         botplayers = G_CountBotPlayers( TEAM_RED );
00419         //
00420         if (humanplayers + botplayers < minplayers) {
00421             G_AddRandomBot( TEAM_RED );
00422         } else if (humanplayers + botplayers > minplayers && botplayers) {
00423             G_RemoveRandomBot( TEAM_RED );
00424         }
00425         //
00426         humanplayers = G_CountHumanPlayers( TEAM_BLUE );
00427         botplayers = G_CountBotPlayers( TEAM_BLUE );
00428         //
00429         if (humanplayers + botplayers < minplayers) {
00430             G_AddRandomBot( TEAM_BLUE );
00431         } else if (humanplayers + botplayers > minplayers && botplayers) {
00432             G_RemoveRandomBot( TEAM_BLUE );
00433         }
00434     }
00435     else if (g_gametype.integer == GT_TOURNAMENT ) {
00436         if (minplayers >= g_maxclients.integer) {
00437             minplayers = g_maxclients.integer-1;
00438         }
00439         humanplayers = G_CountHumanPlayers( -1 );
00440         botplayers = G_CountBotPlayers( -1 );
00441         //
00442         if (humanplayers + botplayers < minplayers) {
00443             G_AddRandomBot( TEAM_FREE );
00444         } else if (humanplayers + botplayers > minplayers && botplayers) {
00445             // try to remove spectators first
00446             if (!G_RemoveRandomBot( TEAM_SPECTATOR )) {
00447                 // just remove the bot that is playing
00448                 G_RemoveRandomBot( -1 );
00449             }
00450         }
00451     }
00452     else if (g_gametype.integer == GT_FFA) {
00453         if (minplayers >= g_maxclients.integer) {
00454             minplayers = g_maxclients.integer-1;
00455         }
00456         humanplayers = G_CountHumanPlayers( TEAM_FREE );
00457         botplayers = G_CountBotPlayers( TEAM_FREE );
00458         //
00459         if (humanplayers + botplayers < minplayers) {
00460             G_AddRandomBot( TEAM_FREE );
00461         } else if (humanplayers + botplayers > minplayers && botplayers) {
00462             G_RemoveRandomBot( TEAM_FREE );
00463         }
00464     }
00465 }

Here is the call graph for this function:

int G_CountBotPlayers int  team  ) 
 

Definition at line 362 of file g_bot.c.

References botSpawnQueue, cl, level_locals_t::clients, g_entities, g_maxclients, gclient_t, i, vmCvar_t::integer, level, n, gentity_s::r, botSpawnQueue_t::spawnTime, entityShared_t::svFlags, and level_locals_t::time.

Referenced by G_CheckMinimumPlayers().

00362                                   {
00363     int i, n, num;
00364     gclient_t   *cl;
00365 
00366     num = 0;
00367     for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00368         cl = level.clients + i;
00369         if ( cl->pers.connected != CON_CONNECTED ) {
00370             continue;
00371         }
00372         if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00373             continue;
00374         }
00375         if ( team >= 0 && cl->sess.sessionTeam != team ) {
00376             continue;
00377         }
00378         num++;
00379     }
00380     for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00381         if( !botSpawnQueue[n].spawnTime ) {
00382             continue;
00383         }
00384         if ( botSpawnQueue[n].spawnTime > level.time ) {
00385             continue;
00386         }
00387         num++;
00388     }
00389     return num;
00390 }

int G_CountHumanPlayers int  team  ) 
 

Definition at line 336 of file g_bot.c.

References cl, level_locals_t::clients, g_entities, g_maxclients, gclient_t, i, vmCvar_t::integer, level, gentity_s::r, and entityShared_t::svFlags.

Referenced by G_CheckMinimumPlayers().

00336                                     {
00337     int i, num;
00338     gclient_t   *cl;
00339 
00340     num = 0;
00341     for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00342         cl = level.clients + i;
00343         if ( cl->pers.connected != CON_CONNECTED ) {
00344             continue;
00345         }
00346         if ( g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT ) {
00347             continue;
00348         }
00349         if ( team >= 0 && cl->sess.sessionTeam != team ) {
00350             continue;
00351         }
00352         num++;
00353     }
00354     return num;
00355 }

const char* G_GetArenaInfoByMap const char *  map  ) 
 

Definition at line 194 of file g_bot.c.

References g_arenaInfos, Info_ValueForKey(), n, and Q_stricmp().

Referenced by G_InitBots().

00194                                                    {
00195     int         n;
00196 
00197     for( n = 0; n < g_numArenas; n++ ) {
00198         if( Q_stricmp( Info_ValueForKey( g_arenaInfos[n], "map" ), map ) == 0 ) {
00199             return g_arenaInfos[n];
00200         }
00201     }
00202 
00203     return NULL;
00204 }

Here is the call graph for this function:

char* G_GetBotInfoByName const char *  name  ) 
 

Definition at line 943 of file g_bot.c.

References g_botInfos, Info_ValueForKey(), n, name, Q_stricmp(), and value.

Referenced by G_AddBot().

00943                                              {
00944     int     n;
00945     char    *value;
00946 
00947     for ( n = 0; n < g_numBots ; n++ ) {
00948         value = Info_ValueForKey( g_botInfos[n], "name" );
00949         if ( !Q_stricmp( value, name ) ) {
00950             return g_botInfos[n];
00951         }
00952     }
00953 
00954     return NULL;
00955 }

Here is the call graph for this function:

char* G_GetBotInfoByNumber int  num  ) 
 

Definition at line 929 of file g_bot.c.

References g_botInfos, S_COLOR_RED, trap_Printf(), and va().

00929                                       {
00930     if( num < 0 || num >= g_numBots ) {
00931         trap_Printf( va( S_COLOR_RED "Invalid bot number: %i\n", num ) );
00932         return NULL;
00933     }
00934     return g_botInfos[num];
00935 }

Here is the call graph for this function:

void G_InitBots qboolean  restart  ) 
 

Definition at line 962 of file g_bot.c.

References atoi, bot_minplayers, CVAR_SERVERINFO, g_gametype, G_GetArenaInfoByMap(), G_LoadArenas(), G_LoadBots(), G_SpawnBots(), Info_ValueForKey(), Q_stricmp(), Q_strncpyz(), trap_Cvar_Register(), trap_Cvar_Set(), and trap_GetServerinfo().

Referenced by G_InitGame().

00962                                     {
00963     int         fragLimit;
00964     int         timeLimit;
00965     const char  *arenainfo;
00966     char        *strValue;
00967     int         basedelay;
00968     char        map[MAX_QPATH];
00969     char        serverinfo[MAX_INFO_STRING];
00970 
00971     G_LoadBots();
00972     G_LoadArenas();
00973 
00974     trap_Cvar_Register( &bot_minplayers, "bot_minplayers", "0", CVAR_SERVERINFO );
00975 
00976     if( g_gametype.integer == GT_SINGLE_PLAYER ) {
00977         trap_GetServerinfo( serverinfo, sizeof(serverinfo) );
00978         Q_strncpyz( map, Info_ValueForKey( serverinfo, "mapname" ), sizeof(map) );
00979         arenainfo = G_GetArenaInfoByMap( map );
00980         if ( !arenainfo ) {
00981             return;
00982         }
00983 
00984         strValue = Info_ValueForKey( arenainfo, "fraglimit" );
00985         fragLimit = atoi( strValue );
00986         if ( fragLimit ) {
00987             trap_Cvar_Set( "fraglimit", strValue );
00988         }
00989         else {
00990             trap_Cvar_Set( "fraglimit", "0" );
00991         }
00992 
00993         strValue = Info_ValueForKey( arenainfo, "timelimit" );
00994         timeLimit = atoi( strValue );
00995         if ( timeLimit ) {
00996             trap_Cvar_Set( "timelimit", strValue );
00997         }
00998         else {
00999             trap_Cvar_Set( "timelimit", "0" );
01000         }
01001 
01002         if ( !fragLimit && !timeLimit ) {
01003             trap_Cvar_Set( "fraglimit", "10" );
01004             trap_Cvar_Set( "timelimit", "0" );
01005         }
01006 
01007         basedelay = BOT_BEGIN_DELAY_BASE;
01008         strValue = Info_ValueForKey( arenainfo, "special" );
01009         if( Q_stricmp( strValue, "training" ) == 0 ) {
01010             basedelay += 10000;
01011         }
01012 
01013         if( !restart ) {
01014             G_SpawnBots( Info_ValueForKey( arenainfo, "bots" ), basedelay );
01015         }
01016     }
01017 }

Here is the call graph for this function:

void G_LoadArenas void   )  [static]
 

Definition at line 153 of file g_bot.c.

References CVAR_INIT, CVAR_ROM, g_arenaInfos, G_LoadArenasFromFile(), g_numArenas, i, Info_SetValueForKey(), n, strcat(), strcpy(), vmCvar_t::string, strlen(), trap_Cvar_Register(), trap_FS_GetFileList(), trap_Printf(), and va().

Referenced by G_InitBots().

00153                                  {
00154     int         numdirs;
00155     vmCvar_t    arenasFile;
00156     char        filename[128];
00157     char        dirlist[1024];
00158     char*       dirptr;
00159     int         i, n;
00160     int         dirlen;
00161 
00162     g_numArenas = 0;
00163 
00164     trap_Cvar_Register( &arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM );
00165     if( *arenasFile.string ) {
00166         G_LoadArenasFromFile(arenasFile.string);
00167     }
00168     else {
00169         G_LoadArenasFromFile("scripts/arenas.txt");
00170     }
00171 
00172     // get all arenas from .arena files
00173     numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024 );
00174     dirptr  = dirlist;
00175     for (i = 0; i < numdirs; i++, dirptr += dirlen+1) {
00176         dirlen = strlen(dirptr);
00177         strcpy(filename, "scripts/");
00178         strcat(filename, dirptr);
00179         G_LoadArenasFromFile(filename);
00180     }
00181     trap_Printf( va( "%i arenas parsed\n", g_numArenas ) );
00182     
00183     for( n = 0; n < g_numArenas; n++ ) {
00184         Info_SetValueForKey( g_arenaInfos[n], "num", va( "%i", n ) );
00185     }
00186 }

Here is the call graph for this function:

void G_LoadArenasFromFile char *  filename  )  [static]
 

Definition at line 125 of file g_bot.c.

References f, fileHandle_t, FS_READ, g_arenaInfos, g_numArenas, G_ParseInfos(), MAX_ARENAS, MAX_ARENAS_TEXT, S_COLOR_RED, trap_FS_FCloseFile(), trap_FS_FOpenFile(), trap_FS_Read(), trap_Printf(), and va().

Referenced by G_LoadArenas().

00125                                                    {
00126     int             len;
00127     fileHandle_t    f;
00128     char            buf[MAX_ARENAS_TEXT];
00129 
00130     len = trap_FS_FOpenFile( filename, &f, FS_READ );
00131     if ( !f ) {
00132         trap_Printf( va( S_COLOR_RED "file not found: %s\n", filename ) );
00133         return;
00134     }
00135     if ( len >= MAX_ARENAS_TEXT ) {
00136         trap_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) );
00137         trap_FS_FCloseFile( f );
00138         return;
00139     }
00140 
00141     trap_FS_Read( buf, len, f );
00142     buf[len] = 0;
00143     trap_FS_FCloseFile( f );
00144 
00145     g_numArenas += G_ParseInfos( buf, MAX_ARENAS - g_numArenas, &g_arenaInfos[g_numArenas] );
00146 }

Here is the call graph for this function:

void G_LoadBots void   )  [static]
 

Definition at line 887 of file g_bot.c.

References CVAR_INIT, CVAR_ROM, G_LoadBotsFromFile(), g_numBots, i, strcat(), strcpy(), vmCvar_t::string, strlen(), trap_Cvar_Register(), trap_Cvar_VariableIntegerValue(), trap_FS_GetFileList(), trap_Printf(), and va().

Referenced by G_InitBots().

00887                                {
00888     vmCvar_t    botsFile;
00889     int         numdirs;
00890     char        filename[128];
00891     char        dirlist[1024];
00892     char*       dirptr;
00893     int         i;
00894     int         dirlen;
00895 
00896     if ( !trap_Cvar_VariableIntegerValue( "bot_enable" ) ) {
00897         return;
00898     }
00899 
00900     g_numBots = 0;
00901 
00902     trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM );
00903     if( *botsFile.string ) {
00904         G_LoadBotsFromFile(botsFile.string);
00905     }
00906     else {
00907         G_LoadBotsFromFile("scripts/bots.txt");
00908     }
00909 
00910     // get all bots from .bot files
00911     numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 );
00912     dirptr  = dirlist;
00913     for (i = 0; i < numdirs; i++, dirptr += dirlen+1) {
00914         dirlen = strlen(dirptr);
00915         strcpy(filename, "scripts/");
00916         strcat(filename, dirptr);
00917         G_LoadBotsFromFile(filename);
00918     }
00919     trap_Printf( va( "%i bots parsed\n", g_numBots ) );
00920 }

Here is the call graph for this function:

void G_LoadBotsFromFile char *  filename  )  [static]
 

Definition at line 859 of file g_bot.c.

References f, fileHandle_t, FS_READ, g_botInfos, g_numBots, G_ParseInfos(), MAX_BOTS, MAX_BOTS_TEXT, S_COLOR_RED, trap_FS_FCloseFile(), trap_FS_FOpenFile(), trap_FS_Read(), trap_Printf(), and va().

Referenced by G_LoadBots().

00859                                                  {
00860     int             len;
00861     fileHandle_t    f;
00862     char            buf[MAX_BOTS_TEXT];
00863 
00864     len = trap_FS_FOpenFile( filename, &f, FS_READ );
00865     if ( !f ) {
00866         trap_Printf( va( S_COLOR_RED "file not found: %s\n", filename ) );
00867         return;
00868     }
00869     if ( len >= MAX_BOTS_TEXT ) {
00870         trap_Printf( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) );
00871         trap_FS_FCloseFile( f );
00872         return;
00873     }
00874 
00875     trap_FS_Read( buf, len, f );
00876     buf[len] = 0;
00877     trap_FS_FCloseFile( f );
00878 
00879     g_numBots += G_ParseInfos( buf, MAX_BOTS - g_numBots, &g_botInfos[g_numBots] );
00880 }

Here is the call graph for this function:

int G_ParseInfos char *  buf,
int  max,
char *  infos[]
 

Definition at line 69 of file g_bot.c.

References COM_Parse(), COM_ParseExt(), Com_Printf(), count, G_Alloc(), Info_SetValueForKey(), MAX_ARENAS, Q_strncpyz(), qfalse, qtrue, strcmp(), strcpy(), strlen(), token, and va().

Referenced by G_LoadArenasFromFile(), and G_LoadBotsFromFile().

00069                                                       {
00070     char    *token;
00071     int     count;
00072     char    key[MAX_TOKEN_CHARS];
00073     char    info[MAX_INFO_STRING];
00074 
00075     count = 0;
00076 
00077     while ( 1 ) {
00078         token = COM_Parse( &buf );
00079         if ( !token[0] ) {
00080             break;
00081         }
00082         if ( strcmp( token, "{" ) ) {
00083             Com_Printf( "Missing { in info file\n" );
00084             break;
00085         }
00086 
00087         if ( count == max ) {
00088             Com_Printf( "Max infos exceeded\n" );
00089             break;
00090         }
00091 
00092         info[0] = '\0';
00093         while ( 1 ) {
00094             token = COM_ParseExt( &buf, qtrue );
00095             if ( !token[0] ) {
00096                 Com_Printf( "Unexpected end of info file\n" );
00097                 break;
00098             }
00099             if ( !strcmp( token, "}" ) ) {
00100                 break;
00101             }
00102             Q_strncpyz( key, token, sizeof( key ) );
00103 
00104             token = COM_ParseExt( &buf, qfalse );
00105             if ( !token[0] ) {
00106                 strcpy( token, "<NULL>" );
00107             }
00108             Info_SetValueForKey( info, key, token );
00109         }
00110         //NOTE: extra space for arena number
00111         infos[count] = G_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1);
00112         if (infos[count]) {
00113             strcpy(infos[count], info);
00114             count++;
00115         }
00116     }
00117     return count;
00118 }

Here is the call graph for this function:

void G_RemoveQueuedBotBegin int  clientNum  ) 
 

Definition at line 525 of file g_bot.c.

References botSpawnQueue, botSpawnQueue_t::clientNum, n, and botSpawnQueue_t::spawnTime.

Referenced by ClientDisconnect().

00525                                              {
00526     int     n;
00527 
00528     for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00529         if( botSpawnQueue[n].clientNum == clientNum ) {
00530             botSpawnQueue[n].spawnTime = 0;
00531             return;
00532         }
00533     }
00534 }

int G_RemoveRandomBot int  team  ) 
 

Definition at line 307 of file g_bot.c.

References cl, level_locals_t::clients, EXEC_INSERT, g_entities, g_maxclients, gclient_t, i, vmCvar_t::integer, level, Q_CleanStr(), gentity_s::r, strcpy(), entityShared_t::svFlags, trap_SendConsoleCommand(), and va().

Referenced by G_CheckMinimumPlayers().

00307                                   {
00308     int i;
00309     char netname[36];
00310     gclient_t   *cl;
00311 
00312     for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00313         cl = level.clie