codemp/ui/ui_gameinfo.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 //
00004 // gameinfo.c
00005 //
00006 
00007 #include "ui_local.h"
00008 
00009 
00010 //
00011 // arena and bot info
00012 //
00013 
00014 
00015 int                             ui_numBots;
00016 static char             *ui_botInfos[MAX_BOTS];
00017 
00018 static int              ui_numArenas;
00019 static char             *ui_arenaInfos[MAX_ARENAS];
00020 
00021 /*
00022 ===============
00023 UI_ParseInfos
00024 ===============
00025 */
00026 int UI_ParseInfos( char *buf, int max, char *infos[] ) {
00027         char    *token;
00028         int             count;
00029         char    key[MAX_TOKEN_CHARS];
00030         char    info[MAX_INFO_STRING];
00031 
00032         count = 0;
00033 
00034         while ( 1 ) {
00035                 token = COM_Parse( (const char **)&buf );
00036                 if ( !token[0] ) {
00037                         break;
00038                 }
00039                 if ( strcmp( token, "{" ) ) {
00040                         Com_Printf( "Missing { in info file\n" );
00041                         break;
00042                 }
00043 
00044                 if ( count == max ) {
00045                         Com_Printf( "Max infos exceeded\n" );
00046                         break;
00047                 }
00048 
00049                 info[0] = '\0';
00050                 while ( 1 ) {
00051                         token = COM_ParseExt( (const char **)&buf, qtrue );
00052                         if ( !token[0] ) {
00053                                 Com_Printf( "Unexpected end of info file\n" );
00054                                 break;
00055                         }
00056                         if ( !strcmp( token, "}" ) ) {
00057                                 break;
00058                         }
00059                         Q_strncpyz( key, token, sizeof( key ) );
00060 
00061                         token = COM_ParseExt( (const char **)&buf, qfalse );
00062                         if ( !token[0] ) {
00063                                 strcpy( token, "<NULL>" );
00064                         }
00065                         Info_SetValueForKey( info, key, token );
00066                 }
00067                 //NOTE: extra space for arena number
00068                 infos[count] = (char *) UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1);
00069                 if (infos[count]) {
00070                         strcpy(infos[count], info);
00071 #ifndef FINAL_BUILD
00072                         if (trap_Cvar_VariableValue("com_buildScript"))
00073                         {
00074                                 char *botFile = Info_ValueForKey(info, "personality");
00075                                 if (botFile && botFile[0])
00076                                 {
00077                                         int fh = 0;
00078                                         trap_FS_FOpenFile(botFile, &fh, FS_READ);
00079                                         if (fh)
00080                                         {
00081                                                 trap_FS_FCloseFile(fh);
00082                                         }
00083                                 }
00084                         }
00085 #endif
00086                         count++;
00087                 }
00088         }
00089         return count;
00090 }
00091 
00092 /*
00093 ===============
00094 UI_LoadArenasFromFile
00095 ===============
00096 */
00097 static void UI_LoadArenasFromFile( char *filename ) {
00098         int                             len;
00099         fileHandle_t    f;
00100         char                    buf[MAX_ARENAS_TEXT];
00101 
00102         len = trap_FS_FOpenFile( filename, &f, FS_READ );
00103         if ( !f ) {
00104                 trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) );
00105                 return;
00106         }
00107         if ( len >= MAX_ARENAS_TEXT ) {
00108                 trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) );
00109                 trap_FS_FCloseFile( f );
00110                 return;
00111         }
00112 
00113         trap_FS_Read( buf, len, f );
00114         buf[len] = 0;
00115         trap_FS_FCloseFile( f );
00116 
00117         ui_numArenas += UI_ParseInfos( buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas] );
00118 }
00119 
00120 /*
00121 ===============
00122 UI_LoadArenas
00123 ===============
00124 */
00125 void UI_LoadArenas( void ) {
00126         int                     numdirs;
00127         char            filename[128];
00128         char            dirlist[1024];
00129         char*           dirptr;
00130         int                     i, n;
00131         int                     dirlen;
00132         char            *type;
00133 
00134         ui_numArenas = 0;
00135         uiInfo.mapCount = 0;
00136 
00137         // get all arenas from .arena files
00138         numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024 );
00139         dirptr  = dirlist;
00140         for (i = 0; i < numdirs; i++, dirptr += dirlen+1) {
00141                 dirlen = strlen(dirptr);
00142                 strcpy(filename, "scripts/");
00143                 strcat(filename, dirptr);
00144                 UI_LoadArenasFromFile(filename);
00145         }
00146 //      trap_Print( va( "%i arenas parsed\n", ui_numArenas ) );
00147         if (UI_OutOfMemory()) {
00148                 trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all arenas\n");
00149         }
00150 
00151         for( n = 0; n < ui_numArenas; n++ ) {
00152                 // determine type
00153 
00154                 uiInfo.mapList[uiInfo.mapCount].cinematic = -1;
00155                 uiInfo.mapList[uiInfo.mapCount].mapLoadName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "map"));
00156                 uiInfo.mapList[uiInfo.mapCount].mapName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "longname"));
00157                 uiInfo.mapList[uiInfo.mapCount].levelShot = -1;
00158                 uiInfo.mapList[uiInfo.mapCount].imageName = String_Alloc(va("levelshots/%s", uiInfo.mapList[uiInfo.mapCount].mapLoadName));
00159                 uiInfo.mapList[uiInfo.mapCount].typeBits = 0;
00160 
00161                 type = Info_ValueForKey( ui_arenaInfos[n], "type" );
00162                 // if no type specified, it will be treated as "ffa"
00163                 if( *type ) {
00164                         if( strstr( type, "ffa" ) ) {
00165                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_FFA);
00166                         }
00167                         if( strstr( type, "holocron" ) ) {
00168                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_HOLOCRON);
00169                         }
00170                         if( strstr( type, "jedimaster" ) ) {
00171                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_JEDIMASTER);
00172                         }
00173                         if( strstr( type, "duel" ) ) {
00174                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_DUEL);
00175                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_POWERDUEL);
00176                         }
00177                         if( strstr( type, "powerduel" ) ) {
00178                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_DUEL);
00179                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_POWERDUEL);
00180                         }
00181                         if( strstr( type, "siege" ) ) {
00182                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_SIEGE);
00183                         }
00184                         if( strstr( type, "ctf" ) ) {
00185                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_CTF);
00186                         }
00187                         if( strstr( type, "cty" ) ) {
00188                                 uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_CTY);
00189                         }
00190                 } else {
00191                         uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_FFA);
00192                 }
00193 
00194                 uiInfo.mapCount++;
00195                 if (uiInfo.mapCount >= MAX_MAPS) {
00196                         break;
00197                 }
00198         }
00199 }
00200 
00201 
00202 /*
00203 ===============
00204 UI_LoadBotsFromFile
00205 ===============
00206 */
00207 static void UI_LoadBotsFromFile( char *filename ) {
00208         int                             len;
00209         fileHandle_t    f;
00210         char                    buf[MAX_BOTS_TEXT];
00211         char                    *stopMark;
00212 
00213         len = trap_FS_FOpenFile( filename, &f, FS_READ );
00214         if ( !f ) {
00215                 trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) );
00216                 return;
00217         }
00218         if ( len >= MAX_BOTS_TEXT ) {
00219                 trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) );
00220                 trap_FS_FCloseFile( f );
00221                 return;
00222         }
00223 
00224         trap_FS_Read( buf, len, f );
00225         buf[len] = 0;
00226 
00227         stopMark = strstr(buf, "@STOPHERE");
00228 
00229         //This bot is in place as a mark for modview's bot viewer.
00230         //If we hit it just stop and trace back to the beginning of the bot define and cut the string off.
00231         //This is only done in the UI and not the game so that "test" bots can be added manually and still
00232         //not show up in the menu.
00233         if (stopMark)
00234         {
00235                 int startPoint = stopMark - buf;
00236 
00237                 while (buf[startPoint] != '{')
00238                 {
00239                         startPoint--;
00240                 }
00241 
00242                 buf[startPoint] = 0;
00243         }
00244 
00245         trap_FS_FCloseFile( f );
00246 
00247         COM_Compress(buf);
00248 
00249         ui_numBots += UI_ParseInfos( buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots] );
00250 }
00251 
00252 /*
00253 ===============
00254 UI_LoadBots
00255 ===============
00256 */
00257 void UI_LoadBots( void ) {
00258         vmCvar_t        botsFile;
00259         int                     numdirs;
00260         char            filename[128];
00261         char            dirlist[1024];
00262         char*           dirptr;
00263         int                     i;
00264         int                     dirlen;
00265 
00266         ui_numBots = 0;
00267 
00268         trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM );
00269         if( *botsFile.string ) {
00270                 UI_LoadBotsFromFile(botsFile.string);
00271         }
00272         else {
00273                 UI_LoadBotsFromFile("botfiles/bots.txt");
00274         }
00275 
00276         // get all bots from .bot files
00277         numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 );
00278         dirptr  = dirlist;
00279         for (i = 0; i < numdirs; i++, dirptr += dirlen+1) {
00280                 dirlen = strlen(dirptr);
00281                 strcpy(filename, "scripts/");
00282                 strcat(filename, dirptr);
00283                 UI_LoadBotsFromFile(filename);
00284         }
00285 //      trap_Print( va( "%i bots parsed\n", ui_numBots ) );
00286 }
00287 
00288 
00289 /*
00290 ===============
00291 UI_GetBotInfoByNumber
00292 ===============
00293 */
00294 char *UI_GetBotInfoByNumber( int num ) {
00295         if( num < 0 || num >= ui_numBots ) {
00296                 trap_Print( va( S_COLOR_RED "Invalid bot number: %i\n", num ) );
00297                 return NULL;
00298         }
00299         return ui_botInfos[num];
00300 }
00301 
00302 
00303 /*
00304 ===============
00305 UI_GetBotInfoByName
00306 ===============
00307 */
00308 char *UI_GetBotInfoByName( const char *name ) {
00309         int             n;
00310         char    *value;
00311 
00312         for ( n = 0; n < ui_numBots ; n++ ) {
00313                 value = Info_ValueForKey( ui_botInfos[n], "name" );
00314                 if ( !Q_stricmp( value, name ) ) {
00315                         return ui_botInfos[n];
00316                 }
00317         }
00318 
00319         return NULL;
00320 }
00321 
00322 int UI_GetNumBots() {
00323         return ui_numBots;
00324 }
00325 
00326 
00327 char *UI_GetBotNameByNumber( int num ) {
00328         char *info = UI_GetBotInfoByNumber(num);
00329         if (info) {
00330                 return Info_ValueForKey( info, "name" );
00331         }
00332         return "Kyle";
00333 }