codemp/game/g_bot.c File Reference

#include "g_local.h"
#include "../namespace_begin.h"
#include "../namespace_end.h"

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

float trap_Cvar_VariableValue (const char *var_name)
int G_ParseInfos (char *buf, int max, char *infos[])
int G_GetMapTypeBits (char *type)
qboolean G_DoesMapSupportGametype (const char *mapname, int gametype)
const char * G_RefreshNextMap (int gametype, qboolean forced)
const char * G_GetArenaInfoByMap (const char *map)
void G_AddRandomBot (int team)
int G_RemoveRandomBot (int team)
int G_CountHumanPlayers (int team)
int G_CountBotPlayers (int team)
void G_CheckMinimumPlayers (void)
void G_CheckBotSpawn (void)
void G_RemoveQueuedBotBegin (int clientNum)
qboolean G_BotConnect (int clientNum, qboolean restart)
void Svcmd_AddBot_f (void)
void Svcmd_BotList_f (void)
char * G_GetBotInfoByNumber (int num)
char * G_GetBotInfoByName (const char *name)
void LoadPath_ThisLevel (void)
void G_InitBots (qboolean restart)

Variables

int g_numArenas
vmCvar_t bot_minplayers
gentity_tpodium1
gentity_tpodium2
gentity_tpodium3


Define Documentation

#define BOT_BEGIN_DELAY_BASE   2000
 

Definition at line 16 of file g_bot.c.

#define BOT_BEGIN_DELAY_INCREMENT   1500
 

Definition at line 17 of file g_bot.c.

#define BOT_SPAWN_QUEUE_DEPTH   16
 

Definition at line 19 of file g_bot.c.

Referenced by G_CheckBotSpawn(), G_CountBotPlayers(), and G_RemoveQueuedBotBegin().


Function Documentation

void G_AddRandomBot int  team  ) 
 

Definition at line 370 of file g_bot.c.

References playerState_s::clientNum, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, EXEC_INSERT, g_entities, g_gametype, g_maxclients, gclient_t, GT_SIEGE, Info_ValueForKey(), vmCvar_t::integer, level, clientPersistant_t::netname, gclient_s::pers, gclient_s::ps, Q_CleanStr(), Q_stricmp(), random, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::siegeDesiredTeam, strncpy(), SVF_BOT, TEAM_BLUE, TEAM_RED, trap_Cvar_VariableValue(), trap_SendConsoleCommand(), and va().

Referenced by G_CheckMinimumPlayers().

00370                                 {
00371         int             i, n, num;
00372         float   skill;
00373         char    *value, netname[36], *teamstr;
00374         gclient_t       *cl;
00375 
00376         num = 0;
00377         for ( n = 0; n < g_numBots ; n++ ) {
00378                 value = Info_ValueForKey( g_botInfos[n], "name" );
00379                 //
00380                 for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00381                         cl = level.clients + i;
00382                         if ( cl->pers.connected != CON_CONNECTED ) {
00383                                 continue;
00384                         }
00385                         if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00386                                 continue;
00387                         }
00388                         if (g_gametype.integer == GT_SIEGE)
00389                         {
00390                                 if ( team >= 0 && cl->sess.siegeDesiredTeam != team ) {
00391                                         continue;
00392                                 }
00393                         }
00394                         else
00395                         {
00396                                 if ( team >= 0 && cl->sess.sessionTeam != team ) {
00397                                         continue;
00398                                 }
00399                         }
00400                         if ( !Q_stricmp( value, cl->pers.netname ) ) {
00401                                 break;
00402                         }
00403                 }
00404                 if (i >= g_maxclients.integer) {
00405                         num++;
00406                 }
00407         }
00408         num = random() * num;
00409         for ( n = 0; n < g_numBots ; n++ ) {
00410                 value = Info_ValueForKey( g_botInfos[n], "name" );
00411                 //
00412                 for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00413                         cl = level.clients + i;
00414                         if ( cl->pers.connected != CON_CONNECTED ) {
00415                                 continue;
00416                         }
00417                         if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00418                                 continue;
00419                         }
00420                         if (g_gametype.integer == GT_SIEGE)
00421                         {
00422                                 if ( team >= 0 && cl->sess.siegeDesiredTeam != team ) {
00423                                         continue;
00424                                 }
00425                         }
00426                         else
00427                         {
00428                                 if ( team >= 0 && cl->sess.sessionTeam != team ) {
00429                                         continue;
00430                                 }
00431                         }
00432                         if ( !Q_stricmp( value, cl->pers.netname ) ) {
00433                                 break;
00434                         }
00435                 }
00436                 if (i >= g_maxclients.integer) {
00437                         num--;
00438                         if (num <= 0) {
00439                                 skill = trap_Cvar_VariableValue( "g_spSkill" );
00440                                 if (team == TEAM_RED) teamstr = "red";
00441                                 else if (team == TEAM_BLUE) teamstr = "blue";
00442                                 else teamstr = "";
00443                                 strncpy(netname, value, sizeof(netname)-1);
00444                                 netname[sizeof(netname)-1] = '\0';
00445                                 Q_CleanStr(netname);
00446                                 trap_SendConsoleCommand( EXEC_INSERT, va("addbot \"%s\" %f %s %i\n", netname, skill, teamstr, 0) );
00447                                 return;
00448                         }
00449                 }
00450         }
00451 }

qboolean G_BotConnect int  clientNum,
qboolean  restart
 

Definition at line 765 of file g_bot.c.

References atof(), bot_settings_t, BotAISetupClient(), Info_ValueForKey(), MAX_INFO_STRING, bot_settings_s::personalityfile, Q_strncpyz(), qboolean, qfalse, qtrue, bot_settings_s::skill, bot_settings_s::team, trap_DropClient(), and trap_GetUserinfo().

Referenced by ClientConnect().

00765                                                          {
00766         bot_settings_t  settings;
00767         char                    userinfo[MAX_INFO_STRING];
00768 
00769         trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) );
00770 
00771         Q_strncpyz( settings.personalityfile, Info_ValueForKey( userinfo, "personality" ), sizeof(settings.personalityfile) );
00772         settings.skill = atof( Info_ValueForKey( userinfo, "skill" ) );
00773         Q_strncpyz( settings.team, Info_ValueForKey( userinfo, "team" ), sizeof(settings.team) );
00774 
00775         if (!BotAISetupClient( clientNum, &settings, restart )) {
00776                 trap_DropClient( clientNum, "BotAISetupClient failed" );
00777                 return qfalse;
00778         }
00779 
00780         return qtrue;
00781 }

void G_CheckBotSpawn void   ) 
 

Definition at line 694 of file g_bot.c.

References BOT_SPAWN_QUEUE_DEPTH, ClientBegin(), G_CheckMinimumPlayers(), level, qfalse, botSpawnQueue_t::spawnTime, and level_locals_t::time.

Referenced by BotAIStartFrame().

00694                              {
00695         int             n;
00696 
00697         G_CheckMinimumPlayers();
00698 
00699         for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00700                 if( !botSpawnQueue[n].spawnTime ) {
00701                         continue;
00702                 }
00703                 if ( botSpawnQueue[n].spawnTime > level.time ) {
00704                         continue;
00705                 }
00706                 ClientBegin( botSpawnQueue[n].clientNum, qfalse );
00707                 botSpawnQueue[n].spawnTime = 0;
00708 
00709                 /*
00710                 if( g_gametype.integer == GT_SINGLE_PLAYER ) {
00711                         trap_GetUserinfo( botSpawnQueue[n].clientNum, userinfo, sizeof(userinfo) );
00712                         PlayerIntroSound( Info_ValueForKey (userinfo, "model") );
00713                 }
00714                 */
00715         }
00716 }

void G_CheckMinimumPlayers void   ) 
 

Definition at line 566 of file g_bot.c.

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

Referenced by G_CheckBotSpawn().

00566                                    {
00567         int minplayers;
00568         int humanplayers, botplayers;
00569         static int checkminimumplayers_time;
00570 
00571         if (g_gametype.integer == GT_SIEGE)
00572         {
00573                 return;
00574         }
00575 
00576         if (level.intermissiontime) return;
00577         //only check once each 10 seconds
00578         if (checkminimumplayers_time > level.time - 10000) {
00579                 return;
00580         }
00581         checkminimumplayers_time = level.time;
00582         trap_Cvar_Update(&bot_minplayers);
00583         minplayers = bot_minplayers.integer;
00584         if (minplayers <= 0) return;
00585 
00586         if (minplayers > g_maxclients.integer)
00587         {
00588                 minplayers = g_maxclients.integer;
00589         }
00590 
00591         humanplayers = G_CountHumanPlayers( -1 );
00592         botplayers = G_CountBotPlayers( -1 );
00593 
00594         if ((humanplayers+botplayers) < minplayers)
00595         {
00596                 G_AddRandomBot(-1);
00597         }
00598         else if ((humanplayers+botplayers) > minplayers && botplayers)
00599         {
00600                 // try to remove spectators first
00601                 if (!G_RemoveRandomBot(TEAM_SPECTATOR))
00602                 {
00603                         // just remove the bot that is playing
00604                         G_RemoveRandomBot(-1);
00605                 }
00606         }
00607 
00608         /*
00609         if (g_gametype.integer >= GT_TEAM) {
00610                 int humanplayers2, botplayers2;
00611                 if (minplayers >= g_maxclients.integer / 2) {
00612                         minplayers = (g_maxclients.integer / 2) -1;
00613                 }
00614 
00615                 humanplayers = G_CountHumanPlayers( TEAM_RED );
00616                 botplayers = G_CountBotPlayers( TEAM_RED );
00617                 humanplayers2 = G_CountHumanPlayers( TEAM_BLUE );
00618                 botplayers2 = G_CountBotPlayers( TEAM_BLUE );
00619                 //
00620                 if ((humanplayers+botplayers+humanplayers2+botplayers) < minplayers)
00621                 {
00622                         if ((humanplayers+botplayers) < (humanplayers2+botplayers2))
00623                         {
00624                                 G_AddRandomBot( TEAM_RED );
00625                         }
00626                         else
00627                         {
00628                                 G_AddRandomBot( TEAM_BLUE );
00629                         }
00630                 }
00631                 else if ((humanplayers+botplayers+humanplayers2+botplayers) > minplayers && botplayers)
00632                 {
00633                         if ((humanplayers+botplayers) < (humanplayers2+botplayers2))
00634                         {
00635                                 G_RemoveRandomBot( TEAM_BLUE );
00636                         }
00637                         else
00638                         {
00639                                 G_RemoveRandomBot( TEAM_RED );
00640                         }
00641                 }
00642         }
00643         else if (g_gametype.integer == GT_DUEL || g_gametype.integer == GT_POWERDUEL) {
00644                 if (minplayers >= g_maxclients.integer) {
00645                         minplayers = g_maxclients.integer-1;
00646                 }
00647                 humanplayers = G_CountHumanPlayers( -1 );
00648                 botplayers = G_CountBotPlayers( -1 );
00649                 //
00650                 if (humanplayers + botplayers < minplayers) {
00651                         G_AddRandomBot( TEAM_FREE );
00652                 } else if (humanplayers + botplayers > minplayers && botplayers) {
00653                         // try to remove spectators first
00654                         if (!G_RemoveRandomBot( TEAM_SPECTATOR )) {
00655                                 // just remove the bot that is playing
00656                                 G_RemoveRandomBot( -1 );
00657                         }
00658                 }
00659         }
00660         else if (g_gametype.integer == GT_FFA) {
00661                 if (minplayers >= g_maxclients.integer) {
00662                         minplayers = g_maxclients.integer-1;
00663                 }
00664                 humanplayers = G_CountHumanPlayers( TEAM_FREE );
00665                 botplayers = G_CountBotPlayers( TEAM_FREE );
00666                 //
00667                 if (humanplayers + botplayers < minplayers) {
00668                         G_AddRandomBot( TEAM_FREE );
00669                 } else if (humanplayers + botplayers > minplayers && botplayers) {
00670                         G_RemoveRandomBot( TEAM_FREE );
00671                 }
00672         }
00673         else if (g_gametype.integer == GT_HOLOCRON || g_gametype.integer == GT_JEDIMASTER) {
00674                 if (minplayers >= g_maxclients.integer) {
00675                         minplayers = g_maxclients.integer-1;
00676                 }
00677                 humanplayers = G_CountHumanPlayers( TEAM_FREE );
00678                 botplayers = G_CountBotPlayers( TEAM_FREE );
00679                 //
00680                 if (humanplayers + botplayers < minplayers) {
00681                         G_AddRandomBot( TEAM_FREE );
00682                 } else if (humanplayers + botplayers > minplayers && botplayers) {
00683                         G_RemoveRandomBot( TEAM_FREE );
00684                 }
00685         }
00686         */
00687 }

int G_CountBotPlayers int  team  ) 
 

Definition at line 522 of file g_bot.c.

References BOT_SPAWN_QUEUE_DEPTH, playerState_s::clientNum, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, g_entities, g_gametype, g_maxclients, gclient_t, GT_SIEGE, vmCvar_t::integer, level, gclient_s::pers, gclient_s::ps, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::siegeDesiredTeam, botSpawnQueue_t::spawnTime, SVF_BOT, and level_locals_t::time.

Referenced by G_CheckMinimumPlayers().

00522                                   {
00523         int i, n, num;
00524         gclient_t       *cl;
00525 
00526         num = 0;
00527         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00528                 cl = level.clients + i;
00529                 if ( cl->pers.connected != CON_CONNECTED ) {
00530                         continue;
00531                 }
00532                 if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00533                         continue;
00534                 }
00535                 if (g_gametype.integer == GT_SIEGE)
00536                 {
00537                         if ( team >= 0 && cl->sess.siegeDesiredTeam != team ) {
00538                                 continue;
00539                         }
00540                 }
00541                 else
00542                 {
00543                         if ( team >= 0 && cl->sess.sessionTeam != team ) {
00544                                 continue;
00545                         }
00546                 }
00547                 num++;
00548         }
00549         for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00550                 if( !botSpawnQueue[n].spawnTime ) {
00551                         continue;
00552                 }
00553                 if ( botSpawnQueue[n].spawnTime > level.time ) {
00554                         continue;
00555                 }
00556                 num++;
00557         }
00558         return num;
00559 }

int G_CountHumanPlayers int  team  ) 
 

Definition at line 496 of file g_bot.c.

References playerState_s::clientNum, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, g_entities, g_maxclients, gclient_t, vmCvar_t::integer, level, gclient_s::pers, gclient_s::ps, gclient_s::sess, clientSession_t::sessionTeam, and SVF_BOT.

Referenced by G_CheckMinimumPlayers().

00496                                     {
00497         int i, num;
00498         gclient_t       *cl;
00499 
00500         num = 0;
00501         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00502                 cl = level.clients + i;
00503                 if ( cl->pers.connected != CON_CONNECTED ) {
00504                         continue;
00505                 }
00506                 if ( g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT ) {
00507                         continue;
00508                 }
00509                 if ( team >= 0 && cl->sess.sessionTeam != team ) {
00510                         continue;
00511                 }
00512                 num++;
00513         }
00514         return num;
00515 }

qboolean G_DoesMapSupportGametype const char *  mapname,
int  gametype
 

Definition at line 168 of file g_bot.c.

References G_GetMapTypeBits(), g_numArenas, Info_ValueForKey(), NULL, Q_stricmp(), qboolean, qfalse, and qtrue.

Referenced by Cmd_CallVote_f().

00169 {
00170         int                     typeBits = 0;
00171         int                     thisLevel = -1;
00172         int                     n = 0;
00173         char            *type = NULL;
00174 
00175         if (!g_arenaInfos[0])
00176         {
00177                 return qfalse;
00178         }
00179 
00180         if (!mapname || !mapname[0])
00181         {
00182                 return qfalse;
00183         }
00184 
00185         for( n = 0; n < g_numArenas; n++ )
00186         {
00187                 type = Info_ValueForKey( g_arenaInfos[n], "map" );
00188 
00189                 if (Q_stricmp(mapname, type) == 0)
00190                 {
00191                         thisLevel = n;
00192                         break;
00193                 }
00194         }
00195 
00196         if (thisLevel == -1)
00197         {
00198                 return qfalse;
00199         }
00200 
00201         type = Info_ValueForKey(g_arenaInfos[thisLevel], "type");
00202 
00203         typeBits = G_GetMapTypeBits(type);
00204         if (typeBits & (1 << gametype))
00205         { //the map in question supports the gametype in question, so..
00206                 return qtrue;
00207         }
00208 
00209         return qfalse;
00210 }

const char* G_GetArenaInfoByMap const char *  map  ) 
 

Definition at line 326 of file g_bot.c.

References g_numArenas, Info_ValueForKey(), NULL, and Q_stricmp().

Referenced by Cmd_CallVote_f().

00326                                                    {
00327         int                     n;
00328 
00329         for( n = 0; n < g_numArenas; n++ ) {
00330                 if( Q_stricmp( Info_ValueForKey( g_arenaInfos[n], "map" ), map ) == 0 ) {
00331                         return g_arenaInfos[n];
00332                 }
00333         }
00334 
00335         return NULL;
00336 }

char* G_GetBotInfoByName const char *  name  ) 
 

Definition at line 1276 of file g_bot.c.

References Info_ValueForKey(), name, NULL, and Q_stricmp().

01276                                              {
01277         int             n;
01278         char    *value;
01279 
01280         for ( n = 0; n < g_numBots ; n++ ) {
01281                 value = Info_ValueForKey( g_botInfos[n], "name" );
01282                 if ( !Q_stricmp( value, name ) ) {
01283                         return g_botInfos[n];
01284                 }
01285         }
01286 
01287         return NULL;
01288 }

char* G_GetBotInfoByNumber int  num  ) 
 

Definition at line 1262 of file g_bot.c.

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

01262                                       {
01263         if( num < 0 || num >= g_numBots ) {
01264                 trap_Printf( va( S_COLOR_RED "Invalid bot number: %i\n", num ) );
01265                 return NULL;
01266         }
01267         return g_botInfos[num];
01268 }

int G_GetMapTypeBits char *  type  ) 
 

Definition at line 129 of file g_bot.c.

References GT_CTF, GT_CTY, GT_DUEL, GT_FFA, GT_HOLOCRON, GT_JEDIMASTER, GT_POWERDUEL, GT_SIEGE, GT_TEAM, and strstr().

Referenced by G_DoesMapSupportGametype(), and G_RefreshNextMap().

00130 {
00131         int typeBits = 0;
00132 
00133         if( *type ) {
00134                 if( strstr( type, "ffa" ) ) {
00135                         typeBits |= (1 << GT_FFA);
00136                         typeBits |= (1 << GT_TEAM);
00137                 }
00138                 if( strstr( type, "holocron" ) ) {
00139                         typeBits |= (1 << GT_HOLOCRON);
00140                 }
00141                 if( strstr( type, "jedimaster" ) ) {
00142                         typeBits |= (1 << GT_JEDIMASTER);
00143                 }
00144                 if( strstr( type, "duel" ) ) {
00145                         typeBits |= (1 << GT_DUEL);
00146                         typeBits |= (1 << GT_POWERDUEL);
00147                 }
00148                 if( strstr( type, "powerduel" ) ) {
00149                         typeBits |= (1 << GT_DUEL);
00150                         typeBits |= (1 << GT_POWERDUEL);
00151                 }
00152                 if( strstr( type, "siege" ) ) {
00153                         typeBits |= (1 << GT_SIEGE);
00154                 }
00155                 if( strstr( type, "ctf" ) ) {
00156                         typeBits |= (1 << GT_CTF);
00157                 }
00158                 if( strstr( type, "cty" ) ) {
00159                         typeBits |= (1 << GT_CTY);
00160                 }
00161         } else {
00162                 typeBits |= (1 << GT_FFA);
00163         }
00164 
00165         return typeBits;
00166 }

void G_InitBots qboolean  restart  ) 
 

Definition at line 1299 of file g_bot.c.

References bot_minplayers, CVAR_SERVERINFO, LoadPath_ThisLevel(), and trap_Cvar_Register().

Referenced by G_InitGame().

01299                                     {
01300         G_LoadBots();
01301         G_LoadArenas();
01302 
01303         trap_Cvar_Register( &bot_minplayers, "bot_minplayers", "0", CVAR_SERVERINFO );
01304 
01305         //rww - new bot route stuff
01306         LoadPath_ThisLevel();
01307         //end rww
01308 }

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

Definition at line 50 of file g_bot.c.

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

00050                                                       {
00051         char    *token;
00052         int             count;
00053         char    key[MAX_TOKEN_CHARS];
00054         char    info[MAX_INFO_STRING];
00055 
00056         count = 0;
00057 
00058         while ( 1 ) {
00059                 token = COM_Parse( (const char **)(&buf) );
00060                 if ( !token[0] ) {
00061                         break;
00062                 }
00063                 if ( strcmp( token, "{" ) ) {
00064                         Com_Printf( "Missing { in info file\n" );
00065                         break;
00066                 }
00067 
00068                 if ( count == max ) {
00069                         Com_Printf( "Max infos exceeded\n" );
00070                         break;
00071                 }
00072 
00073                 info[0] = '\0';
00074                 while ( 1 ) {
00075                         token = COM_ParseExt( (const char **)(&buf), qtrue );
00076                         if ( !token[0] ) {
00077                                 Com_Printf( "Unexpected end of info file\n" );
00078                                 break;
00079                         }
00080                         if ( !strcmp( token, "}" ) ) {
00081                                 break;
00082                         }
00083                         Q_strncpyz( key, token, sizeof( key ) );
00084 
00085                         token = COM_ParseExt( (const char **)(&buf), qfalse );
00086                         if ( !token[0] ) {
00087                                 strcpy( token, "<NULL>" );
00088                         }
00089                         Info_SetValueForKey( info, key, token );
00090                 }
00091                 //NOTE: extra space for arena number
00092                 infos[count] = (char *) G_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1);
00093                 if (infos[count]) {
00094                         strcpy(infos[count], info);
00095                         count++;
00096                 }
00097         }
00098         return count;
00099 }

const char* G_RefreshNextMap int  gametype,
qboolean  forced
 

Definition at line 213 of file g_bot.c.

References CVAR_ROM, CVAR_SERVERINFO, g_autoMapCycle, G_GetMapTypeBits(), g_numArenas, Info_ValueForKey(), vmCvar_t::integer, NULL, Q_stricmp(), qboolean, qfalse, qtrue, vmCvar_t::string, trap_Cvar_Register(), trap_Cvar_Set(), and va().

Referenced by CheckVote().

00214 {
00215         int                     typeBits = 0;
00216         int                     thisLevel = 0;
00217         int                     desiredMap = 0;
00218         int                     n = 0;
00219         char            *type = NULL;
00220         qboolean        loopingUp = qfalse;
00221         vmCvar_t        mapname;
00222 
00223         if (!g_autoMapCycle.integer && !forced)
00224         {
00225                 return NULL;
00226         }
00227 
00228         if (!g_arenaInfos[0])
00229         {
00230                 return NULL;
00231         }
00232 
00233         trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );
00234         for( n = 0; n < g_numArenas; n++ )
00235         {
00236                 type = Info_ValueForKey( g_arenaInfos[n], "map" );
00237 
00238                 if (Q_stricmp(mapname.string, type) == 0)
00239                 {
00240                         thisLevel = n;
00241                         break;
00242                 }
00243         }
00244 
00245         desiredMap = thisLevel;
00246 
00247         n = thisLevel+1;
00248         while (n != thisLevel)
00249         { //now cycle through the arena list and find the next map that matches the gametype we're in
00250                 if (!g_arenaInfos[n] || n >= g_numArenas)
00251                 {
00252                         if (loopingUp)
00253                         { //this shouldn't happen, but if it does we have a null entry break in the arena file
00254                           //if this is the case just break out of the loop instead of sticking in an infinite loop
00255                                 break;
00256                         }
00257                         n = 0;
00258                         loopingUp = qtrue;
00259                 }
00260 
00261                 type = Info_ValueForKey(g_arenaInfos[n], "type");
00262                 
00263                 typeBits = G_GetMapTypeBits(type);
00264                 if (typeBits & (1 << gametype))
00265                 {
00266                         desiredMap = n;
00267                         break;
00268                 }
00269 
00270                 n++;
00271         }
00272 
00273         if (desiredMap == thisLevel)
00274         { //If this is the only level for this game mode or we just can't find a map for this game mode, then nextmap
00275           //will always restart.
00276                 trap_Cvar_Set( "nextmap", "map_restart 0");
00277         }
00278         else
00279         { //otherwise we have a valid nextmap to cycle to, so use it.
00280                 type = Info_ValueForKey( g_arenaInfos[desiredMap], "map" );
00281                 trap_Cvar_Set( "nextmap", va("map %s", type));
00282         }
00283 
00284         return Info_ValueForKey( g_arenaInfos[desiredMap], "map" );
00285 }

void G_RemoveQueuedBotBegin int  clientNum  ) 
 

Definition at line 748 of file g_bot.c.

References BOT_SPAWN_QUEUE_DEPTH, botSpawnQueue_t::clientNum, and botSpawnQueue_t::spawnTime.

Referenced by ClientDisconnect().

00748                                              {
00749         int             n;
00750 
00751         for( n = 0; n < BOT_SPAWN_QUEUE_DEPTH; n++ ) {
00752                 if( botSpawnQueue[n].clientNum == clientNum ) {
00753                         botSpawnQueue[n].spawnTime = 0;
00754                         return;
00755                 }
00756         }
00757 }

int G_RemoveRandomBot int  team  ) 
 

Definition at line 458 of file g_bot.c.

References playerState_s::clientNum, level_locals_t::clients, CON_CONNECTED, clientPersistant_t::connected, EXEC_INSERT, g_entities, g_gametype, g_maxclients, gclient_t, GT_SIEGE, vmCvar_t::integer, level, clientPersistant_t::netname, gclient_s::pers, gclient_s::ps, Q_CleanStr(), qfalse, qtrue, gclient_s::sess, clientSession_t::sessionTeam, clientSession_t::siegeDesiredTeam, strcpy(), SVF_BOT, trap_SendConsoleCommand(), and va().

Referenced by G_CheckMinimumPlayers().

00458                                   {
00459         int i;
00460         char netname[36];
00461         gclient_t       *cl;
00462 
00463         for ( i=0 ; i< g_maxclients.integer ; i++ ) {
00464                 cl = level.clients + i;
00465                 if ( cl->pers.connected != CON_CONNECTED ) {
00466                         continue;
00467                 }
00468                 if ( !(g_entities[cl->ps.clientNum].r.svFlags & SVF_BOT) ) {
00469                         continue;
00470                 }
00471                 if (g_gametype.integer == GT_SIEGE)
00472                 {
00473                         if ( team >= 0 && cl->sess.siegeDesiredTeam != team ) {
00474                                 continue;
00475                         }
00476                 }
00477                 else
00478                 {
00479                         if ( team >= 0 && cl->sess.sessionTeam != team ) {
00480                                 continue;
00481                         }
00482                 }
00483                 strcpy(netname, cl->pers.netname);
00484                 Q_CleanStr(netname);
00485                 trap_SendConsoleCommand( EXEC_INSERT, va("kick \"%s\"\n", netname) );
00486                 return qtrue;
00487         }
00488         return qfalse;
00489 }

void LoadPath_ThisLevel void   ) 
 

Definition at line 3347 of file ai_wpnav.c.

References BeginAutoPathRoutine(), bot_normgpath, bot_wp_edit, gentity_s::classname, Com_Printf(), CVAR_CHEAT, CVAR_ROM, CVAR_SERVERINFO, eFlagBlue, eFlagRed, g_entities, g_RMG, gBotEdit, gentity_t, gLevelFlags, vmCvar_t::integer, gentity_s::inuse, level, LEVELFLAG_NOPOINTPREDICTION, LoadPathData(), NULL, level_locals_t::num_entities, strcmp(), vmCvar_t::string, trap_Cvar_Register(), trap_Cvar_Update(), and vmCvar_t::value.

Referenced by G_InitBots().

03348 {
03349         vmCvar_t        mapname;
03350         int                     i = 0;
03351         gentity_t       *ent = NULL;
03352 
03353         trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );
03354 
03355         if (g_RMG.integer)
03356         { //If RMG, generate the path on-the-fly
03357 #ifdef _XBOX
03358                 assert(0);
03359 #else
03360                 trap_Cvar_Register(&bot_normgpath, "bot_normgpath", "1", CVAR_CHEAT);
03361                 //note: This is disabled for now as I'm using standard bot nav
03362                 //on premade terrain levels.
03363 
03364                 if (!bot_normgpath.integer)
03365                 { //autopath the random map
03366                         BeginAutoPathRoutine();
03367                 }
03368                 else
03369                 { //try loading standard nav data
03370                         LoadPathData(mapname.string);
03371                 }
03372 
03373                 gLevelFlags |= LEVELFLAG_NOPOINTPREDICTION;
03374 #endif
03375         }
03376         else
03377         {
03378                 if (LoadPathData(mapname.string) == 2)
03379                 {
03380                         //enter "edit" mode if cheats enabled?
03381                 }
03382         }
03383 
03384         trap_Cvar_Update(&bot_wp_edit);
03385 
03386         if (bot_wp_edit.value)
03387         {
03388                 gBotEdit = 1;
03389         }
03390         else
03391         {
03392                 gBotEdit = 0;
03393         }
03394 
03395         //set the flag entities
03396         while (i < level.num_entities)
03397         {
03398                 ent = &g_entities[i];
03399 
03400                 if (ent && ent->inuse && ent->classname)
03401                 {
03402                         if (!eFlagRed && strcmp(ent->classname, "team_CTF_redflag") == 0)
03403                         {
03404                                 eFlagRed = ent;
03405                         }
03406                         else if (!eFlagBlue && strcmp(ent->classname, "team_CTF_blueflag") == 0)
03407                         {
03408                                 eFlagBlue = ent;
03409                         }
03410 
03411                         if (eFlagRed && eFlagBlue)
03412                         {
03413                                 break;
03414                         }
03415                 }
03416 
03417                 i++;
03418         }
03419 
03420 #ifdef PAINFULLY_DEBUGGING_THROUGH_VM
03421         Com_Printf("BOT PATHING IS COMPLETE.\n");
03422 #endif
03423 }

void Svcmd_AddBot_f void   ) 
 

Definition at line 1038 of file g_bot.c.

References atof(), atoi(), level, MAX_TOKEN_CHARS, name, level_locals_t::startTime, level_locals_t::time, trap_Argv(), trap_Cvar_VariableIntegerValue(), trap_Printf(), and trap_SendServerCommand().

Referenced by ConsoleCommand().

01038                             {
01039         float                   skill;
01040         int                             delay;
01041         char                    name[MAX_TOKEN_CHARS];
01042         char                    altname[MAX_TOKEN_CHARS];
01043         char                    string[MAX_TOKEN_CHARS];
01044         char                    team[MAX_TOKEN_CHARS];
01045 
01046         // are bots enabled?
01047         if ( !trap_Cvar_VariableIntegerValue( "bot_enable" ) ) {
01048                 return;
01049         }
01050 
01051         // name
01052         trap_Argv( 1, name, sizeof( name ) );
01053         if ( !name[0] ) {
01054                 trap_Printf( "Usage: Addbot <botname> [skill 1-5] [team] [msec delay] [altname]\n" );
01055                 return;
01056         }
01057 
01058         // skill
01059         trap_Argv( 2, string, sizeof( string ) );
01060         if ( !string[0] ) {
01061                 skill = 4;
01062         }
01063         else {
01064                 skill = atof( string );
01065         }
01066 
01067         // team
01068         trap_Argv( 3, team, sizeof( team ) );
01069 
01070         // delay
01071         trap_Argv( 4, string, sizeof( string ) );
01072         if ( !string[0] ) {
01073                 delay = 0;
01074         }
01075         else {
01076                 delay = atoi( string );
01077         }
01078 
01079         // alternative name
01080         trap_Argv( 5, altname, sizeof( altname ) );
01081 
01082         G_AddBot( name, skill, team, delay, altname );
01083 
01084         // if this was issued during gameplay and we are playing locally,
01085         // go ahead and load the bot's media immediately
01086         if ( level.time - level.startTime > 1000 &&
01087                 trap_Cvar_VariableIntegerValue( "cl_running" ) ) {
01088                 trap_SendServerCommand( -1, "loaddefered\n" );  // FIXME: spelled wrong, but not changing for demo
01089         }
01090 }

void Svcmd_BotList_f void   ) 
 

Definition at line 1097 of file g_bot.c.

References Info_ValueForKey(), MAX_TOKEN_CHARS, name, strcpy(), trap_Printf(), and va().

Referenced by ConsoleCommand().

01097                              {
01098         int i;
01099         char name[MAX_TOKEN_CHARS];
01100         char funname[MAX_TOKEN_CHARS];
01101         char model[MAX_TOKEN_CHARS];
01102         char personality[MAX_TOKEN_CHARS];
01103 
01104         trap_Printf("^1name             model            personality              funname\n");
01105         for (i = 0; i < g_numBots; i++) {
01106                 strcpy(name, Info_ValueForKey( g_botInfos[i], "name" ));
01107                 if ( !*name ) {
01108                         strcpy(name, "Padawan");
01109                 }
01110                 strcpy(funname, Info_ValueForKey( g_botInfos[i], "funname" ));
01111                 if ( !*funname ) {
01112                         strcpy(funname, "");
01113                 }
01114                 strcpy(model, Info_ValueForKey( g_botInfos[i], "model" ));
01115                 if ( !*model ) {
01116                         strcpy(model, "kyle/default");
01117                 }
01118                 strcpy(personality, Info_ValueForKey( g_botInfos[i], "personality"));
01119                 if (!*personality ) {
01120                         strcpy(personality, "botfiles/kyle.jkb");
01121                 }
01122                 trap_Printf(va("%-16s %-16s %-20s %-20s\n", name, model, personality, funname));
01123         }
01124 }

float trap_Cvar_VariableValue const char *  var_name  ) 
 

Definition at line 36 of file g_bot.c.

Referenced by _UI_Init().

00036                                                       {
00037         char buf[128];
00038 
00039         trap_Cvar_VariableStringBuffer(var_name, buf, sizeof(buf));
00040         return atof(buf);
00041 }


Variable Documentation

vmCvar_t bot_minplayers
 

Definition at line 29 of file g_bot.c.

Referenced by G_CheckMinimumPlayers(), and G_InitBots().

int g_numArenas
 

Definition at line 12 of file g_bot.c.

Referenced by G_DoesMapSupportGametype(), G_GetArenaInfoByMap(), and G_RefreshNextMap().

gentity_t* podium1
 

Definition at line 31 of file g_bot.c.

gentity_t* podium2
 

Definition at line 32 of file g_bot.c.

gentity_t* podium3
 

Definition at line 33 of file g_bot.c.