//----------------------------------------------------------------------------- // // $Id$ // //----------------------------------------------------------------------------- // // $Log$ // Revision 1.12 2006/04/14 18:02:06 makro // no message // // Revision 1.11 2003/03/31 01:23:54 jbravo // Fixing 2 compiler warnings // // Revision 1.10 2002/09/08 13:14:47 makro // New code added for the callvote menu map list // // Revision 1.9 2002/07/24 05:28:44 jbravo // Changed rq3ctf to rq3ctb in the .arena parsing code. // // Revision 1.8 2002/06/16 20:06:14 jbravo // Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap" // // Revision 1.7 2002/06/13 15:50:24 makro // Bot list is now sorted alphabetically // // Revision 1.6 2002/05/26 14:37:21 makro // Map list is now sorted alphabetically // // Revision 1.5 2002/03/31 13:23:26 makro // Cleaned things up a little // // Revision 1.4 2002/03/03 21:22:58 makro // no message // // Revision 1.3 2002/02/21 20:10:16 jbravo // Converted files back from M$ format and added cvs headers again. // // //----------------------------------------------------------------------------- // Copyright (C) 1999-2000 Id Software, Inc. // // // gameinfo.c // #include "ui_local.h" // // arena and bot info // int ui_numBots; static char *ui_botInfos[MAX_BOTS]; static int ui_numArenas; static char *ui_arenaInfos[MAX_ARENAS]; //Makro - not used anywhere /* #ifndef MISSIONPACK // bk001206 static int ui_numSinglePlayerArenas; static int ui_numSpecialSinglePlayerArenas; #endif */ //Makro - grouping the gametypes parsed in .arena files typedef struct { char *Name; int Value; } RQ3_GameType_t; static RQ3_GameType_t RQ3_GameTypes[] = { /* {"ffa", 1 << GT_FFA}, {"tourney", 1 << GT_TOURNAMENT}, {"team", 1 << GT_TEAM}, {"rq3tp", 1 << GT_TEAMPLAY}, {"ctf", 1 << GT_CTF}, {"1fctf", 1 << GT_1FCTF}, {"obelisk", 1 << GT_OBELISK}, {"harvester", 1 << GT_HARVESTER}, */ {"rq3dm", 1 << GT_FFA}, {"rq3tdm", 1 << GT_TEAM}, {"rq3tp", 1 << GT_TEAMPLAY}, {"rq3ctb", 1 << GT_CTF}, {"none", 0} }; // static int UI_RQ3_DefaultArenaGameType = 1 << GT_FFA; //end Makro /* =============== UI_ParseInfos =============== */ int UI_ParseInfos(char *buf, int max, char *infos[]) { char *token; int count; char key[MAX_TOKEN_CHARS]; char info[MAX_INFO_STRING]; count = 0; INFINITE_LOOP { token = COM_Parse(&buf); if (!token[0]) { break; } if (strcmp(token, "{")) { Com_Printf("Missing { in info file\n"); break; } if (count == max) { Com_Printf("Max infos exceeded\n"); break; } info[0] = '\0'; INFINITE_LOOP { token = COM_ParseExt(&buf, qtrue); if (!token[0]) { Com_Printf("Unexpected end of info file\n"); break; } if (!strcmp(token, "}")) { break; } Q_strncpyz(key, token, sizeof(key)); token = COM_ParseExt(&buf, qfalse); if (!token[0]) { strcpy(token, ""); } Info_SetValueForKey(info, key, token); } //NOTE: extra space for arena number infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1); if (infos[count]) { strcpy(infos[count], info); count++; } } return count; } /* =============== UI_LoadArenasFromFile =============== */ static void UI_LoadArenasFromFile(char *filename) { int len; fileHandle_t f; char buf[MAX_ARENAS_TEXT]; len = trap_FS_FOpenFile(filename, &f, FS_READ); if (!f) { trap_Print(va(S_COLOR_RED "file not found: %s\n", filename)); return; } if (len >= MAX_ARENAS_TEXT) { trap_Print(va (S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT)); trap_FS_FCloseFile(f); return; } trap_FS_Read(buf, len, f); buf[len] = 0; trap_FS_FCloseFile(f); ui_numArenas += UI_ParseInfos(buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas]); } /* =============== UI_LoadArenas =============== */ void UI_LoadArenas(void) { int numdirs; vmCvar_t arenasFile; char filename[128]; char dirlist[1024]; char *dirptr; int i, n; int dirlen; char *type; ui_numArenas = 0; uiInfo.mapCount = 0; trap_Cvar_Register(&arenasFile, "g_arenasFile", "", CVAR_INIT | CVAR_ROM); if (*arenasFile.string) { UI_LoadArenasFromFile(arenasFile.string); } else { UI_LoadArenasFromFile("scripts/arenas.txt"); } // get all arenas from .arena files numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024); dirptr = dirlist; for (i = 0; i < numdirs; i++, dirptr += dirlen + 1) { dirlen = strlen(dirptr); strcpy(filename, "scripts/"); strcat(filename, dirptr); UI_LoadArenasFromFile(filename); } trap_Print(va("%i arenas parsed\n", ui_numArenas)); if (UI_OutOfMemory()) { trap_Print(S_COLOR_YELLOW "WARNING: not anough memory in pool to load all arenas\n"); } for (n = 0; n < ui_numArenas; n++) { // determine type uiInfo.mapList[uiInfo.mapCount].cinematic = -1; uiInfo.mapList[uiInfo.mapCount].mapLoadName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "map")); uiInfo.mapList[uiInfo.mapCount].mapName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "longname")); uiInfo.mapList[uiInfo.mapCount].levelShot = -1; uiInfo.mapList[uiInfo.mapCount].imageName = String_Alloc(va("levelshots/%s", uiInfo.mapList[uiInfo.mapCount].mapLoadName)); uiInfo.mapList[uiInfo.mapCount].typeBits = 0; type = Info_ValueForKey(ui_arenaInfos[n], "type"); // if no type specified, it will be treated as "ffa" // Makro - I didn't like the old code, hehe /* if( *type ) { if( strstr( type, "ffa" ) ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_FFA); } if( strstr( type, "tourney" ) ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_TOURNAMENT); } if( strstr( type, "ctf" ) ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_CTF); } if( strstr( type, "oneflag" ) ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_1FCTF); } if( strstr( type, "overload" ) ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_OBELISK); } if( strstr( type, "harvester" ) ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_HARVESTER); } } else { uiInfo.mapList[uiInfo.mapCount].typeBits |= (1 << GT_FFA); } */ // Makro - new code if (*type) { for (i = 0; RQ3_GameTypes[i].Value != 0; i++) { if (strstr(type, RQ3_GameTypes[i].Name)) { uiInfo.mapList[uiInfo.mapCount].typeBits |= RQ3_GameTypes[i].Value; } } }// else { // uiInfo.mapList[uiInfo.mapCount].typeBits |= UI_RQ3_DefaultArenaGameType; //} uiInfo.mapCount++; if (uiInfo.mapCount >= MAX_MAPS) { break; } } //Makro - sorting list for (i = 0; i < uiInfo.mapCount - 1; i++) { for (n = i + 1; n < uiInfo.mapCount; n++) { if (Q_stricmp(uiInfo.mapList[i].mapName, uiInfo.mapList[n].mapName) > 0) { mapInfo temp = uiInfo.mapList[i]; uiInfo.mapList[i] = uiInfo.mapList[n]; uiInfo.mapList[n] = temp; } } } } /* =============== UI_LoadBotsFromFile =============== */ static void UI_LoadBotsFromFile(char *filename) { int len; fileHandle_t f; char buf[MAX_BOTS_TEXT]; len = trap_FS_FOpenFile(filename, &f, FS_READ); if (!f) { trap_Print(va(S_COLOR_RED "file not found: %s\n", filename)); return; } if (len >= MAX_BOTS_TEXT) { trap_Print(va(S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT)); trap_FS_FCloseFile(f); return; } trap_FS_Read(buf, len, f); buf[len] = 0; trap_FS_FCloseFile(f); COM_Compress(buf); ui_numBots += UI_ParseInfos(buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots]); } /* =============== UI_LoadBots =============== */ void UI_LoadBots(void) { vmCvar_t botsFile; int numdirs; char filename[128]; char dirlist[1024]; char *dirptr; int i; int dirlen; ui_numBots = 0; trap_Cvar_Register(&botsFile, "g_botsFile", "", CVAR_INIT | CVAR_ROM); if (*botsFile.string) { UI_LoadBotsFromFile(botsFile.string); } else { UI_LoadBotsFromFile("scripts/bots.txt"); } // get all bots from .bot files numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024); dirptr = dirlist; for (i = 0; i < numdirs; i++, dirptr += dirlen + 1) { dirlen = strlen(dirptr); strcpy(filename, "scripts/"); strcat(filename, dirptr); UI_LoadBotsFromFile(filename); } //Makro - sort bot list for (i = 0; i < ui_numBots - 1; i++) { for (dirlen = i + 1; dirlen < ui_numBots; dirlen++) { char *n1 = Info_ValueForKey(ui_botInfos[i], "name"); char *n2 = Info_ValueForKey(ui_botInfos[dirlen], "name"); if (!n1) n1 = "Abbey"; if (!n2) n2 = "Abbey"; if (Q_stricmp(n1, n2) > 0) { dirptr = ui_botInfos[i]; ui_botInfos[i] = ui_botInfos[dirlen]; ui_botInfos[dirlen] = dirptr; } } } trap_Print(va("%i bots parsed\n", ui_numBots)); } /* =============== UI_GetBotInfoByNumber =============== */ char *UI_GetBotInfoByNumber(int num) { if (num < 0 || num >= ui_numBots) { trap_Print(va(S_COLOR_RED "Invalid bot number: %i\n", num)); return NULL; } return ui_botInfos[num]; } /* =============== UI_GetBotInfoByName =============== */ char *UI_GetBotInfoByName(const char *name) { int n; char *value; for (n = 0; n < ui_numBots; n++) { value = Info_ValueForKey(ui_botInfos[n], "name"); if (!Q_stricmp(value, name)) { return ui_botInfos[n]; } } return NULL; } int UI_GetNumBots() { return ui_numBots; } char *UI_GetBotNameByNumber(int num) { char *info = UI_GetBotInfoByNumber(num); if (info) { return Info_ValueForKey(info, "name"); } //Makro - changed from Sarge return "Raver"; }