void UI_SaberLoadParms( void ) { int len, totallen, saberExtFNLen, fileCnt, i; char *holdChar, *marker; char saberExtensionListBuf[2048]; // The list of file names read in fileHandle_t f; char buffer[MAX_MENUFILE]; //ui.Printf( "UI Parsing *.sab saber definitions\n" ); ui_saber_parms_parsed = qtrue; UI_CacheSaberGlowGraphics(); //set where to store the first one totallen = 0; marker = SaberParms; marker[0] = '\0'; //now load in the extra .npc extensions fileCnt = trap_FS_GetFileList("ext_data/sabers", ".sab", saberExtensionListBuf, sizeof(saberExtensionListBuf) ); holdChar = saberExtensionListBuf; for ( i = 0; i < fileCnt; i++, holdChar += saberExtFNLen + 1 ) { saberExtFNLen = strlen( holdChar ); len = trap_FS_FOpenFile( va( "ext_data/sabers/%s", holdChar), &f, FS_READ ); if (!f) { continue; } if ( len == -1 ) { Com_Printf( "UI_SaberLoadParms: error reading %s\n", holdChar ); } else { if (len > sizeof(buffer) ) { Com_Error( ERR_FATAL, "UI_SaberLoadParms: file %s too large to read (max=%d)", holdChar, sizeof(buffer) ); } trap_FS_Read( buffer, len, f ); trap_FS_FCloseFile( f ); buffer[len] = 0; if ( totallen && *(marker-1) == '}' ) {//don't let it end on a } because that should be a stand-alone token strcat( marker, " " ); totallen++; marker++; } len = COM_Compress( buffer ); if ( totallen + len >= MAX_SABER_DATA_SIZE ) { Com_Error( ERR_FATAL, "UI_SaberLoadParms: ran out of space before reading %s\n(you must make the .sab files smaller)", holdChar ); } strcat( marker, buffer ); totallen += len; marker += len; } } }
/* =============== CG_ParseTrailFile Load the trail systems from a trail file =============== */ static bool CG_ParseTrailFile( const char *fileName ) { const char *text_p; int i; int len; char *token; char text[ 32000 ]; char tsName[ MAX_QPATH ]; bool tsNameSet = false; fileHandle_t f; // load the file len = trap_FS_FOpenFile( fileName, &f, fsMode_t::FS_READ ); if ( len <= 0 ) { return false; } if ( len == 0 || len + 1 >= (int) sizeof( text ) ) { trap_FS_FCloseFile( f ); Log::Warn( len ? "trail file %s is too long" : "trail file %s is empty", fileName ); return false; } trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); // parse the text text_p = text; // read optional parameters while ( 1 ) { token = COM_Parse( &text_p ); if ( !*token ) { break; } if ( !Q_stricmp( token, "{" ) ) { if ( tsNameSet ) { //check for name space clashes for ( i = 0; i < numBaseTrailSystems; i++ ) { if ( !Q_stricmp( baseTrailSystems[ i ].name, tsName ) ) { Log::Warn( "a trail system is already named %s", tsName ); return false; } } Q_strncpyz( baseTrailSystems[ numBaseTrailSystems ].name, tsName, MAX_QPATH ); if ( !CG_ParseTrailSystem( &baseTrailSystems[ numBaseTrailSystems ], &text_p, tsName ) ) { Log::Warn( "%s: failed to parse trail system %s", fileName, tsName ); return false; } //start parsing trail systems again tsNameSet = false; if ( numBaseTrailSystems == MAX_BASETRAIL_SYSTEMS ) { Log::Warn( "maximum number of trail systems (%d) reached", MAX_BASETRAIL_SYSTEMS ); return false; } else { numBaseTrailSystems++; } continue; } else { Log::Warn( "unnamed trail system" ); return false; } } if ( !tsNameSet ) { Q_strncpyz( tsName, token, sizeof( tsName ) ); tsNameSet = true; } else { Log::Warn( "trail system already named" ); return false; } } return true; }
void CG_LoadHolsterData (clientInfo_t *ci) {//adjusts the manual holster positional data based on the holster.cfg file associated with the model or simply //use the default values int i; fileHandle_t f; int fLen = 0; char fileBuffer[MAX_HOLSTER_INFO_SIZE]; char holsterTypeValue[MAX_QPATH]; char holsterTypeGroup[MAX_HOLSTER_INFO_SIZE]; char *s; vec3_t vectorData; InitHolsterData(ci); if ( !ci->skinName || !Q_stricmp( "default", ci->skinName ) ) {//try default holster.cfg first fLen = trap_FS_FOpenFile(va("models/players/%s/holster.cfg", ci->modelName), &f, FS_READ); if( !f ) {//no file, use kyle's then. fLen = trap_FS_FOpenFile("models/players/kyle/holster.cfg", &f, FS_READ); } } else {//use the holster.cfg associated with this skin fLen = trap_FS_FOpenFile(va("models/players/%s/holster_%s.cfg", ci->modelName, ci->skinName), &f, FS_READ); if ( !f ) {//fall back to default holster.cfg fLen = trap_FS_FOpenFile(va("models/players/%s/holster.cfg", ci->modelName), &f, FS_READ); } if( !f ) {//still no dice, use kyle's then. fLen = trap_FS_FOpenFile("models/players/kyle/holster.cfg", &f, FS_READ); } } if ( !f || !fLen ) {//couldn't open file or it was empty, just use the defaults return; } if( fLen >= MAX_HOLSTER_INFO_SIZE ) { CG_Printf("Error: holster.cfg for %s is over the holster.cfg filesize limit.\n", ci->modelName); trap_FS_FCloseFile( f ); return; } trap_FS_Read(fileBuffer, fLen, f); trap_FS_FCloseFile( f ); s = fileBuffer; //parse file while( (s = BG_GetNextValueGroup(s, holsterTypeGroup)) != NULL ) { if( !BG_SiegeGetPairedValue(holsterTypeGroup, "holsterType", holsterTypeValue) ) {//couldn't find holster type in group CG_Printf("Error: The holster.cfg for %s appears to be missing a holsterType in one of its define groups.\n", ci->modelName); continue; } i = GetIDForString(holsterTypeTable, holsterTypeValue); if( i == -1 ) {//bad holster type CG_Printf("Error: The holster.cfg for %s has a bad holsterType in one of the define groups.\n", ci->modelName); continue; } if( BG_SiegeGetPairedValue(holsterTypeGroup, "boneIndex", holsterTypeValue) ) {//have bone index data for this holster type, use it if(!Q_stricmp(holsterTypeValue, "disabled") ) {//disable the rendering of this holster type on this model ci->holsterData[i].boneIndex = HOLSTER_NONE; } else { ci->holsterData[i].boneIndex = GetIDForString(holsterBoneTable, holsterTypeValue); } } if( BG_SiegeGetPairedValue(holsterTypeGroup, "posOffset", holsterTypeValue) ) {//parsing positional offset data sscanf (holsterTypeValue, "%f, %f, %f", &vectorData[0], &vectorData[1], &vectorData[2]); VectorCopy(vectorData, ci->holsterData[i].posOffset); //&ci->holsterData[i].posOffset[0], &ci->holsterData[i].posOffset[1], //&ci->holsterData[i].posOffset[2]); } if( BG_SiegeGetPairedValue(holsterTypeGroup, "angOffset", holsterTypeValue) ) {//parsing angular offset sscanf (holsterTypeValue, "%f, %f, %f", &vectorData[0], &vectorData[1], &vectorData[2]); VectorCopy(vectorData, ci->holsterData[i].angOffset); } } #ifdef _DEBUG CG_Printf("Holstered Weapon Data Loaded for %s.\n", ci->modelName); #endif }
void BG_SiegeParseTeamFile(const char *filename) { fileHandle_t f; int len; char teamInfo[2048]; char parseBuf[1024]; char lookString[256]; int i = 1; qboolean success = qtrue; len = trap_FS_FOpenFile(filename, &f, FS_READ); if (!f || len >= 2048) { return; } trap_FS_Read(teamInfo, len, f); trap_FS_FCloseFile(f); teamInfo[len] = 0; if (BG_SiegeGetPairedValue(teamInfo, "name", parseBuf)) { strcpy(bgSiegeTeams[bgNumSiegeTeams].name, parseBuf); } else { Com_Error(ERR_DROP, "Siege team with no name definition"); } //I don't entirely like doing things this way but it's the easiest way. #ifdef CGAME if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", parseBuf)) { bgSiegeTeams[bgNumSiegeTeams].friendlyShader = trap_R_RegisterShaderNoMip(parseBuf); } #else bgSiegeTeams[bgNumSiegeTeams].friendlyShader = 0; #endif bgSiegeTeams[bgNumSiegeTeams].numClasses = 0; if (BG_SiegeGetValueGroup(teamInfo, "Classes", teamInfo)) { while (success && i < MAX_SIEGE_CLASSES) { //keep checking for group values named class# up to MAX_SIEGE_CLASSES until we can't find one. strcpy(lookString, va("class%i", i)); success = BG_SiegeGetPairedValue(teamInfo, lookString, parseBuf); if (!success) { break; } bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] = BG_SiegeFindClassByName(parseBuf); if (!bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses]) { Com_Printf( "Invalid class specified: '%s'\n", parseBuf); } bgSiegeTeams[bgNumSiegeTeams].numClasses++; i++; } } if (!bgSiegeTeams[bgNumSiegeTeams].numClasses) { Com_Error(ERR_DROP, "Team defined with no allowable classes\n"); } //If we get here then it was a success, so increment the team number bgNumSiegeTeams++; }
/* ================= CG_ParseVoiceChats ================= */ int CG_ParseVoiceChats( const char *filename, voiceChatList_t *voiceChatList, int maxVoiceChats ) { int len, i; fileHandle_t f; char buf[MAX_VOICEFILESIZE]; char **p, *ptr; char *token; voiceChat_t *voiceChats; qboolean compress; sfxHandle_t sound; compress = qtrue; if (cg_buildScript.integer) { compress = qfalse; } len = trap_FS_FOpenFile( filename, &f, FS_READ ); if ( !f ) { trap_Print( va( S_COLOR_RED "voice chat file not found: %s\n", filename ) ); return qfalse; } if ( len >= MAX_VOICEFILESIZE ) { trap_Print( va( S_COLOR_RED "voice chat file too large: %s is %i, max allowed is %i\n", filename, len, MAX_VOICEFILESIZE ) ); trap_FS_FCloseFile( f ); return qfalse; } trap_FS_Read( buf, len, f ); buf[len] = 0; trap_FS_FCloseFile( f ); ptr = buf; p = &ptr; Com_sprintf(voiceChatList->name, sizeof(voiceChatList->name), "%s", filename); voiceChats = voiceChatList->voiceChats; for ( i = 0; i < maxVoiceChats; i++ ) { voiceChats[i].id[0] = 0; } token = COM_ParseExt(p, qtrue); if (!token || token[0] == 0) { return qtrue; } if (!Q_stricmp(token, "female")) { voiceChatList->gender = GENDER_FEMALE; } else if (!Q_stricmp(token, "male")) { voiceChatList->gender = GENDER_MALE; } else if (!Q_stricmp(token, "neuter")) { voiceChatList->gender = GENDER_NEUTER; } else { trap_Print( va( S_COLOR_RED "expected gender not found in voice chat file: %s\n", filename ) ); return qfalse; } voiceChatList->numVoiceChats = 0; while ( 1 ) { token = COM_ParseExt(p, qtrue); if (!token || token[0] == 0) { return qtrue; } Com_sprintf(voiceChats[voiceChatList->numVoiceChats].id, sizeof( voiceChats[voiceChatList->numVoiceChats].id ), "%s", token); token = COM_ParseExt(p, qtrue); if (Q_stricmp(token, "{")) { trap_Print( va( S_COLOR_RED "expected { found %s in voice chat file: %s\n", token, filename ) ); return qfalse; } voiceChats[voiceChatList->numVoiceChats].numSounds = 0; while(1) { token = COM_ParseExt(p, qtrue); if (!token || token[0] == 0) { return qtrue; } if (!Q_stricmp(token, "}")) break; //sound = trap_S_RegisterSound( token, compress ); // leilei - speed voiceChats[voiceChatList->numVoiceChats].sounds[voiceChats[voiceChatList->numVoiceChats].numSounds] = sound; token = COM_ParseExt(p, qtrue); if (!token || token[0] == 0) { return qtrue; } Com_sprintf(voiceChats[voiceChatList->numVoiceChats].chats[ voiceChats[voiceChatList->numVoiceChats].numSounds], MAX_CHATSIZE, "%s", token); // if (sound) // leilei - speed voiceChats[voiceChatList->numVoiceChats].numSounds++; if (voiceChats[voiceChatList->numVoiceChats].numSounds >= MAX_VOICESOUNDS) break; } voiceChatList->numVoiceChats++; if (voiceChatList->numVoiceChats >= maxVoiceChats) return qtrue; } return qtrue; }
int CGSyscall_FS_Read( void *buffer, int len, fileHandle_t f ) { trap_FS_Read( buffer, len, f ); return 0; }
qboolean BG_ParseAnimationFile(const char *filename) { char *text_p; int len; int i; char *token; float fps; int skip; fileHandle_t f; int animNum; // load the file if (!BGPAFtextLoaded) { //rww - We are always using the same animation config now. So only load it once. len = trap_FS_FOpenFile( filename, &f, FS_READ ); if ( len <= 0 ) { return qfalse; } if ( len >= sizeof( BGPAFtext ) - 1 ) { //Com_Printf( "File %s too long\n", filename ); return qfalse; } trap_FS_Read( BGPAFtext, len, f ); BGPAFtext[len] = 0; trap_FS_FCloseFile( f ); } else { return qtrue; } // parse the text text_p = BGPAFtext; skip = 0; // quiet the compiler warning //FIXME: have some way of playing anims backwards... negative numFrames? //initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100 for(i = 0; i < MAX_ANIMATIONS; i++) { bgGlobalAnimations[i].firstFrame = 0; bgGlobalAnimations[i].numFrames = 0; bgGlobalAnimations[i].loopFrames = -1; bgGlobalAnimations[i].frameLerp = 100; bgGlobalAnimations[i].initialLerp = 100; } // read information for each frame while(1) { token = COM_Parse( (const char **)(&text_p) ); if ( !token || !token[0]) { break; } animNum = GetIDForString(animTable, token); if(animNum == -1) { //#ifndef FINAL_BUILD #ifdef _DEBUG Com_Printf(S_COLOR_RED"WARNING: Unknown token %s in %s\n", token, filename); #endif continue; } token = COM_Parse( (const char **)(&text_p) ); if ( !token ) { break; } bgGlobalAnimations[animNum].firstFrame = atoi( token ); token = COM_Parse( (const char **)(&text_p) ); if ( !token ) { break; } bgGlobalAnimations[animNum].numFrames = atoi( token ); token = COM_Parse( (const char **)(&text_p) ); if ( !token ) { break; } bgGlobalAnimations[animNum].loopFrames = atoi( token ); token = COM_Parse( (const char **)(&text_p) ); if ( !token ) { break; } fps = atof( token ); if ( fps == 0 ) { fps = 1;//Don't allow divide by zero error } if ( fps < 0 ) {//backwards bgGlobalAnimations[animNum].frameLerp = floor(1000.0f / fps); } else { bgGlobalAnimations[animNum].frameLerp = ceil(1000.0f / fps); } bgGlobalAnimations[animNum].initialLerp = ceil(1000.0f / fabs(fps)); } #ifdef _DEBUG //Check the array, and print the ones that have nothing in them. for(i = 0; i < MAX_ANIMATIONS; i++) { if (animTable[i].name != NULL) // This animation reference exists. { if (bgGlobalAnimations[i].firstFrame <= 0 && bgGlobalAnimations[i].numFrames <=0) { // This is an empty animation reference. Com_Printf("***ANIMTABLE reference #%d (%s) is empty!\n", i, animTable[i].name); } } } #endif // _DEBUG #ifdef CONVENIENT_ANIMATION_FILE_DEBUG_THING SpewDebugStuffToFile(); #endif BGPAFtextLoaded = qtrue; return qtrue; }
/* ============= G_Script_ScriptLoad Loads the script for the current level into the buffer Dini mapscripts support ============= */ void G_Script_ScriptLoad( void ) { char filename[MAX_QPATH]; vmCvar_t mapname; fileHandle_t f = 0; int len = 0; qboolean found = qfalse; trap_Cvar_Register( &g_scriptDebug, "g_scriptDebug", "0", 0 ); level.scriptEntity = NULL; trap_Cvar_VariableStringBuffer( "g_scriptName", filename, sizeof(filename) ); if (strlen( filename ) > 0) { trap_Cvar_Register( &mapname, "g_scriptName", "", CVAR_CHEAT ); } else { trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); } // Dini, mapscript support if(tjg_mapScriptDirectory.string[0]) { G_Printf("%s: checking for custom mapscript...\n", GAMEVERSION); Q_strncpyz(filename, tjg_mapScriptDirectory.string, sizeof(filename)); Q_strcat(filename, sizeof(filename), "/"); Q_strcat( filename, sizeof(filename), mapname.string ); Q_strcat( filename, sizeof(filename), ".script" ); len = trap_FS_FOpenFile( filename, &f, FS_READ ); if(len > 0) { found = qtrue; G_Printf("%s: loaded custom mapscript!\n", GAMEVERSION); } } if(!found) { // Normal behaviour? Q_strncpyz( filename, "maps/", sizeof(filename) ); Q_strcat( filename, sizeof(filename), mapname.string ); Q_strcat( filename, sizeof(filename), ".script" ); len = trap_FS_FOpenFile( filename, &f, FS_READ ); G_Printf("%s: no custom mapscript, using default!\n", GAMEVERSION); } // make sure we clear out the temporary scriptname trap_Cvar_Set( "g_scriptName", "" ); if( len < 0 ) { return; } // END Mad Doc - TDF // Arnout: make sure we terminate the script with a '\0' to prevent parser from choking //level.scriptEntity = G_Alloc( len ); //trap_FS_Read( level.scriptEntity, len, f ); level.scriptEntity = G_Alloc( len + 1 ); trap_FS_Read( level.scriptEntity, len, f ); *(level.scriptEntity + len) = '\0'; // Gordon: and make sure ppl haven't put stuff with uppercase in the string table.. G_Script_EventStringInit(); // Gordon: discard all the comments NOW, so we dont deal with them inside scripts // Gordon: disabling for a sec, wanna check if i can get proper line numbers from error output // COM_Compress( level.scriptEntity ); trap_FS_FCloseFile( f ); }
/* =============== G_ParseMapRotationFile Load the map rotations from a map rotation file =============== */ static qboolean G_ParseMapRotationFile( const char *fileName ) { char *text_p; int i, j, k; int len; char *token; char text[ 20000 ]; char mrName[ MAX_QPATH ]; qboolean mrNameSet = qfalse; fileHandle_t f; // load the file len = trap_FS_FOpenFile( fileName, &f, FS_READ ); if( len < 0 ) return qfalse; if( len == 0 || len >= sizeof( text ) - 1 ) { trap_FS_FCloseFile( f ); G_Printf( S_COLOR_RED "ERROR: map rotation file %s is %s\n", fileName, len == 0 ? "empty" : "too long" ); return qfalse; } trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); // parse the text text_p = text; // read optional parameters while( 1 ) { token = COM_Parse( &text_p ); if( !token ) break; if( !Q_stricmp( token, "" ) ) break; if( !Q_stricmp( token, "{" ) ) { if( mrNameSet ) { //check for name space clashes for( i = 0; i < mapRotations.numRotations; i++ ) { if( !Q_stricmp( mapRotations.rotations[ i ].name, mrName ) ) { G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName ); return qfalse; } } Q_strncpyz( mapRotations.rotations[ mapRotations.numRotations ].name, mrName, MAX_QPATH ); if( !G_ParseMapRotation( &mapRotations.rotations[ mapRotations.numRotations ], &text_p ) ) { G_Printf( S_COLOR_RED "ERROR: %s: failed to parse map rotation %s\n", fileName, mrName ); return qfalse; } //start parsing map rotations again mrNameSet = qfalse; if( mapRotations.numRotations == MAX_MAP_ROTATIONS ) { G_Printf( S_COLOR_RED "ERROR: maximum number of map rotations (%d) reached\n", MAX_MAP_ROTATIONS ); return qfalse; } else mapRotations.numRotations++; continue; } else { G_Printf( S_COLOR_RED "ERROR: unamed map rotation\n" ); return qfalse; } } if( !mrNameSet ) { Q_strncpyz( mrName, token, sizeof( mrName ) ); mrNameSet = qtrue; } else { G_Printf( S_COLOR_RED "ERROR: map rotation already named\n" ); return qfalse; } } for( i = 0; i < mapRotations.numRotations; i++ ) { for( j = 0; j < mapRotations.rotations[ i ].numMaps; j++ ) { if( !G_MapExists( mapRotations.rotations[ i ].maps[ j ].name ) ) { G_Printf( S_COLOR_RED "ERROR: map \"%s\" doesn't exist\n", mapRotations.rotations[ i ].maps[ j ].name ); return qfalse; } for( k = 0; k < mapRotations.rotations[ i ].maps[ j ].numConditions; k++ ) { if( !G_MapExists( mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ) && !G_RotationExists( mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ) ) { G_Printf( S_COLOR_RED "ERROR: conditional destination \"%s\" doesn't exist\n", mapRotations.rotations[ i ].maps[ j ].conditions[ k ].dest ); return qfalse; } } } } return qtrue; }
/* * S_ReadPlaylistFile */ static qboolean S_ReadPlaylistFile( const char *filename, qboolean shuffle ) { int filenum, length; char *tmpname = 0; size_t tmpname_size = 0; char *data, *line, *entry; playlistItem_t items[MAX_PLAYLIST_ITEMS]; int i, numItems = 0; length = trap_FS_FOpenFile( filename, &filenum, FS_READ ); if( length < 0 ) return qfalse; // load the playlist into memory data = S_Malloc( length + 1 ); trap_FS_Read( data, length, filenum ); trap_FS_FCloseFile( filenum ); srand( time( NULL ) ); while( *data ) { size_t s; entry = data; // read the whole line for( line = data; *line != '\0' && *line != '\n'; line++ ); // continue reading from the next character, if possible data = (*line == '\0' ? line : line + 1); *line = '\0'; // trim whitespaces, tabs, etc entry = Q_trim( entry ); // special M3U entry or comment if( !*entry || *entry == '#' ) continue; if( trap_FS_IsUrl( entry ) ) { items[numItems].track = S_AllocTrack( entry ); } else { // append the entry name to playlist path s = strlen( filename ) + 1 + strlen( entry ) + 1; if( s > tmpname_size ) { if( tmpname ) S_Free( tmpname ); tmpname_size = s; tmpname = S_Malloc( tmpname_size ); } Q_strncpyz( tmpname, filename, tmpname_size ); COM_StripFilename( tmpname ); Q_strncatz( tmpname, "/", tmpname_size ); Q_strncatz( tmpname, entry, tmpname_size ); COM_SanitizeFilePath( tmpname ); items[numItems].track = S_AllocTrack( tmpname ); } if( ++numItems == MAX_PLAYLIST_ITEMS ) break; } if( tmpname ) { S_Free( tmpname ); tmpname = NULL; } if( !numItems ) return qfalse; // set the playing order for( i = 0; i < numItems; i++ ) items[i].order = (shuffle ? (rand() % numItems) : i); // sort the playlist R_SortPlaylistItems( numItems, items ); // link the playlist s_bgTrack = items[0].track; for( i = 1; i < numItems; i++ ) { items[i-1].track->next = items[i].track; items[i].track->prev = items[i-1].track; } items[numItems-1].track->next = items[0].track; items[0].track->prev = items[numItems-1].track; return qtrue; }
/* ====================== CG_ParseWeaponFile Parses a configuration file describing a weapon ====================== */ static qboolean CG_ParseWeaponFile( const char *filename, weaponInfo_t *wi ) { char *text_p; int len; char *token; char text[ 20000 ]; fileHandle_t f; weaponMode_t weaponMode = WPM_NONE; // load the file len = trap_FS_FOpenFile( filename, &f, FS_READ ); if( len <= 0 ) return qfalse; if( len >= sizeof( text ) - 1 ) { CG_Printf( "File %s too long\n", filename ); return qfalse; } trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); // parse the text text_p = text; // read optional parameters while( 1 ) { token = COM_Parse( &text_p ); if( !token ) break; if( !Q_stricmp( token, "" ) ) break; if( !Q_stricmp( token, "{" ) ) { if( weaponMode == WPM_NONE ) { CG_Printf( S_COLOR_RED "ERROR: weapon mode section started without a declaration\n" ); return qfalse; } else if( !CG_ParseWeaponModeSection( &wi->wim[ weaponMode ], &text_p ) ) { CG_Printf( S_COLOR_RED "ERROR: failed to parse weapon mode section\n" ); return qfalse; } //start parsing ejectors again weaponMode = WPM_NONE; continue; } else if( !Q_stricmp( token, "primary" ) ) { weaponMode = WPM_PRIMARY; continue; } else if( !Q_stricmp( token, "secondary" ) ) { weaponMode = WPM_SECONDARY; continue; } else if( !Q_stricmp( token, "tertiary" ) ) { weaponMode = WPM_TERTIARY; continue; } else if( !Q_stricmp( token, "weaponModel" ) ) { char path[ MAX_QPATH ]; token = COM_Parse( &text_p ); if( !token ) break; wi->weaponModel = trap_R_RegisterModel( token ); if( !wi->weaponModel ) CG_Printf( S_COLOR_RED "ERROR: weapon model not found %s\n", token ); strcpy( path, token ); COM_StripExtension( path, path, MAX_QPATH ); strcat( path, "_flash.md3" ); wi->flashModel = trap_R_RegisterModel( path ); strcpy( path, token ); COM_StripExtension( path, path, MAX_QPATH ); strcat( path, "_barrel.md3" ); wi->barrelModel = trap_R_RegisterModel( path ); strcpy( path, token ); COM_StripExtension( path, path, MAX_QPATH ); strcat( path, "_hand.md3" ); wi->handsModel = trap_R_RegisterModel( path ); if( !wi->handsModel ) wi->handsModel = trap_R_RegisterModel( "models/weapons2/shotgun/shotgun_hand.md3" ); continue; } else if( !Q_stricmp( token, "idleSound" ) ) { token = COM_Parse( &text_p ); if( !token ) break; wi->readySound = trap_S_RegisterSound( token, qfalse ); continue; } else if( !Q_stricmp( token, "icon" ) ) { token = COM_Parse( &text_p ); if( !token ) break; wi->weaponIcon = wi->ammoIcon = trap_R_RegisterShader( token ); if( !wi->weaponIcon ) CG_Printf( S_COLOR_RED "ERROR: weapon icon not found %s\n", token ); continue; } else if( !Q_stricmp( token, "crosshair" ) ) { int size = 0; token = COM_Parse( &text_p ); if( !token ) break; size = atoi( token ); if( size < 0 ) size = 0; token = COM_Parse( &text_p ); if( !token ) break; wi->crossHair = trap_R_RegisterShader( token ); wi->crossHairSize = size; if( !wi->crossHair ) CG_Printf( S_COLOR_RED "ERROR: weapon crosshair not found %s\n", token ); continue; } else if( !Q_stricmp( token, "disableIn3rdPerson" ) ) { wi->disableIn3rdPerson = qtrue; continue; } Com_Printf( S_COLOR_RED "ERROR: unknown token '%s'\n", token ); return qfalse; } return qtrue; }
void CG_LoadLocations(void) { fileHandle_t f; // handle of file on disk int fLen = trap_FS_FOpenFile(va("maps/%s_loc_override.dat", cgs.rawmapname), &f, FS_READ); // length of the file char fBuffer[MAX_BUFFER]; // buffer to read the file into char message[128] = "\0"; // location description char temp[128] = "\0"; // temporary buffer int x = 0; // x-coord of the location int y = 0; // y-coord of the location int z = 0; // z-coord of the location int p = 0; // current location in the file buffer int t = 0; // current location in the temp buffer if (fLen < 0) { // open the location .dat file that matches the map's name fLen = trap_FS_FOpenFile(va("maps/%s_loc.dat", cgs.rawmapname), &f, FS_READ); if (fLen < 0) { CG_Printf("^dLoadLocations: ^3Warning: ^9No location data found for map ^2%s^9.\n", cgs.rawmapname); return; } } if (fLen >= MAX_BUFFER) { trap_FS_FCloseFile(f); CG_Error("Location file is too big, make it smaller (max = %i bytes)\n", MAX_BUFFER); } trap_FS_Read(&fBuffer, fLen, f); // read the file into the buffer fBuffer[fLen] = '\0'; // make sure it's null-terminated trap_FS_FCloseFile(f); // close the file, we're done with it CG_Printf("^dLoadLocations: ^9location data for map ^2%s ^9loaded\n", cgs.rawmapname); // start parsing! while (p < fLen) { // check for the beginning of a comment if (fBuffer[p++] == '/') { //check for single line comment if (fBuffer[p] == '/') { while (p < fLen && (fBuffer[p] != '\n' && fBuffer[p] != '\r')) { p++; } } // check for multiline comment else if (fBuffer[p] == '*') { while (p < fLen && (fBuffer[p] != '*' && fBuffer[p + 1] != '/')) { p++; } } } // parse the next line while (p < fLen && (fBuffer[p] != '\n' && fBuffer[p] != '\r')) { // grab the x-coord while (p < fLen && fBuffer[p] != ' ') { temp[t++] = fBuffer[p++]; } temp[t] = '\0'; x = atoi(temp); t = 0; memset(&temp, 0, sizeof(temp)); if (p > fLen) { break; } p++; // grab the y-coord while (p < fLen && fBuffer[p] != ' ') { temp[t++] = fBuffer[p++]; } temp[t] = '\0'; y = atoi(temp); t = 0; memset(&temp, 0, sizeof(temp)); if (p > fLen) { break; } p++; // grab the z-coord while (p < fLen && fBuffer[p] != ' ') { temp[t++] = fBuffer[p++]; } temp[t] = '\0'; z = atoi(temp); t = 0; memset(&temp, 0, sizeof(temp)); if (p > fLen) { break; } p++; // grab the description while (p < fLen && fBuffer[p] != '\n' && fBuffer[p] != '\r') { // ignore quotation marks if (fBuffer[p] != '\"') { temp[t++] = fBuffer[p++]; } else { p++; } } temp[t] = '\0'; t = 0; // if @, then keep the previous location name, otherwise, update message if (Q_stricmp(temp, "@")) { strcpy(message, temp); } if (p > fLen) { break; } if ((x != 0 || y != 0 || z != 0) && strlen(message) > 0) { location_t *loc = &cgs.location[cgs.numLocations]; loc->index = cgs.numLocations; strcpy(loc->message, message); loc->origin[0] = x; loc->origin[1] = y; loc->origin[2] = z; cgs.numLocations++; if (cgs.numLocations == MAX_C_LOCATIONS) { CG_Printf("^9Too many locations specifed.\n"); break; } } } } // ok we are succesfull CG_Printf("^2%i ^9locations loaded.\n", cgs.numLocations); cgs.locationsLoaded = qtrue; }
void parseAura(char *path,auraConfig_t *aura){ fileHandle_t auraCFG; int i; char *token,*parse; int fileLength; char fileContents[32000]; if(trap_FS_FOpenFile(path,0,FS_READ)>0){ fileLength = trap_FS_FOpenFile(path,&auraCFG,FS_READ); trap_FS_Read(fileContents,fileLength,auraCFG); fileContents[fileLength] = 0; trap_FS_FCloseFile(auraCFG); parse = fileContents; while(1){ token = COM_Parse(&parse); if(!token[0]){break;} else if(!Q_stricmp(token,"auraExists")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->showAura = strlen(token) == 4 ? qtrue : qfalse; } else if(!Q_stricmp(token,"auraAlways")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->auraAlways = strlen(token) == 4 ? qtrue : qfalse; } else if(!Q_stricmp(token,"hasAuraLight")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->showLight = strlen(token) == 4 ? qtrue : qfalse; } else if(!Q_stricmp(token,"hasAuraTrail")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->showTrail = strlen(token) == 4 ? qtrue : qfalse; } else if(!Q_stricmp(token,"hasAuraDebris")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->generatesDebris = strlen(token) == 4 ? qtrue : qfalse; } else if(!Q_stricmp( token, "auraTagCount")){ for(i = 0;i < 3;i++){ token = COM_Parse(&parse); if(!token[0]){break;} aura->numTags[i] = atoi( token); } } else if(!Q_stricmp( token, "auraShader")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->auraShader = trap_R_RegisterShader(token); } else if(!Q_stricmp( token, "auraTrailShader")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->trailShader = trap_R_RegisterShader(token); } else if(!Q_stricmp( token, "auraTrailWidth")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->trailWidth = atoi(token); } else if(!Q_stricmp( token, "auraChargeLoop")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->chargeLoopSound = trap_S_RegisterSound(token,qfalse); } else if(!Q_stricmp( token, "auraChargeStart")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->chargeStartSound = trap_S_RegisterSound(token,qfalse); } else if(!Q_stricmp( token, "auraBoostLoop")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->boostLoopSound = trap_S_RegisterSound(token,qfalse); } else if(!Q_stricmp( token, "auraBoostStart")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->boostStartSound = trap_S_RegisterSound(token,qfalse); } else if (!Q_stricmp( token, "auraColor")){ for(i = 0;i < 3;i++){ token = COM_Parse(&parse); if(!token[0]){break;} aura->auraColor[i] = atof( token); if(aura->auraColor[i] < 0) aura->auraColor[i] = 0; if(aura->auraColor[i] > 1) aura->auraColor[i] = 1; } } else if(!Q_stricmp( token, "auraLightColor")){ for(i = 0;i < 3;i++){ token = COM_Parse(&parse); if(!token[0]){break;} aura->lightColor[i] = atof( token); if(aura->lightColor[i] < 0) aura->lightColor[i] = 0; if(aura->lightColor[i] > 1) aura->lightColor[i] = 1; } } else if(!Q_stricmp( token, "auraTrailColor")){ for(i = 0;i < 3;i++){ token = COM_Parse(&parse); if(!token[0]){break;} aura->trailColor[i] = atof( token); if(aura->trailColor[i] < 0) aura->trailColor[i] = 0; if(aura->trailColor[i] > 1) aura->trailColor[i] = 1; } } else if(!Q_stricmp( token, "auraScale")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->auraScale = atof(token); } else if(!Q_stricmp( token, "auraLength")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->tailLength = atoi(token); } else if(!Q_stricmp( token, "auraLightMin")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->lightMin = atoi(token); } else if(!Q_stricmp( token, "auraLightMax")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->lightMax = atoi(token); } else if(!Q_stricmp( token, "auraLightGrowthRate")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->lightGrowthRate = atoi(token); } else if(!Q_stricmp(token,"showLightning")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->showLightning = strlen(token) == 4 ? qtrue : qfalse; } else if(!Q_stricmp(token,"lightningShader")){ token = COM_Parse(&parse); if(!token[0]){break;} aura->lightningShader = trap_R_RegisterShaderNoMip(token); } } } }
void BotUtilizePersonality(bot_state_t *bs) { fileHandle_t f; int len, rlen; int failed; int i; //char buf[131072]; char *buf = (char *)B_TempAlloc(131072); char *readbuf, *group; len = trap_FS_FOpenFile(bs->settings.personalityfile, &f, FS_READ); failed = 0; if (!f) { G_Printf(S_COLOR_RED "Error: Specified personality not found\n"); B_TempFree(131072); //buf return; } if (len >= 131072) { G_Printf(S_COLOR_RED "Personality file exceeds maximum length\n"); B_TempFree(131072); //buf return; } trap_FS_Read(buf, len, f); rlen = len; while (len < 131072) { //kill all characters after the file length, since sometimes FS_Read doesn't do that entirely (or so it seems) buf[len] = '\0'; len++; } len = rlen; readbuf = (char *)B_TempAlloc(1024); group = (char *)B_TempAlloc(65536); if (!GetValueGroup(buf, "GeneralBotInfo", group)) { G_Printf(S_COLOR_RED "Personality file contains no GeneralBotInfo group\n"); failed = 1; //set failed so we know to set everything to default values } if (!failed && GetPairedValue(group, "reflex", readbuf)) { bs->skills.reflex = atoi(readbuf); } else { bs->skills.reflex = 100; //default } if (!failed && GetPairedValue(group, "accuracy", readbuf)) { bs->skills.accuracy = atof(readbuf); } else { bs->skills.accuracy = 10; //default } if (!failed && GetPairedValue(group, "turnspeed", readbuf)) { bs->skills.turnspeed = atof(readbuf); } else { bs->skills.turnspeed = 0.01f; //default } if (!failed && GetPairedValue(group, "turnspeed_combat", readbuf)) { bs->skills.turnspeed_combat = atof(readbuf); } else { bs->skills.turnspeed_combat = 0.05f; //default } if (!failed && GetPairedValue(group, "maxturn", readbuf)) { bs->skills.maxturn = atof(readbuf); } else { bs->skills.maxturn = 360; //default } if (!failed && GetPairedValue(group, "perfectaim", readbuf)) { bs->skills.perfectaim = atoi(readbuf); } else { bs->skills.perfectaim = 0; //default } if (!failed && GetPairedValue(group, "chatability", readbuf)) { bs->canChat = atoi(readbuf); } else { bs->canChat = 0; //default } if (!failed && GetPairedValue(group, "chatfrequency", readbuf)) { bs->chatFrequency = atoi(readbuf); } else { bs->chatFrequency = 5; //default } if (!failed && GetPairedValue(group, "hatelevel", readbuf)) { bs->loved_death_thresh = atoi(readbuf); } else { bs->loved_death_thresh = 3; //default } if (!failed && GetPairedValue(group, "camper", readbuf)) { bs->isCamper = atoi(readbuf); } else { bs->isCamper = 0; //default } if (!failed && GetPairedValue(group, "saberspecialist", readbuf)) { bs->saberSpecialist = atoi(readbuf); } else { bs->saberSpecialist = 0; //default } if (!failed && GetPairedValue(group, "forceinfo", readbuf)) { Com_sprintf(bs->forceinfo, sizeof(bs->forceinfo), "%s\0", readbuf); } else { Com_sprintf(bs->forceinfo, sizeof(bs->forceinfo), "%s\0", DEFAULT_FORCEPOWERS); } i = 0; while (i < MAX_CHAT_BUFFER_SIZE) { //clear out the chat buffer for this bot gBotChatBuffer[bs->client][i] = '\0'; i++; } if (bs->canChat) { if (!ReadChatGroups(bs, buf)) { bs->canChat = 0; } } if (GetValueGroup(buf, "BotWeaponWeights", group)) { if (GetPairedValue(group, "WP_STUN_BATON", readbuf)) { bs->botWeaponWeights[WP_STUN_BATON] = atoi(readbuf); } if (GetPairedValue(group, "WP_SABER", readbuf)) { bs->botWeaponWeights[WP_SABER] = atoi(readbuf); } if (GetPairedValue(group, "WP_BRYAR_PISTOL", readbuf)) { bs->botWeaponWeights[WP_BRYAR_PISTOL] = atoi(readbuf); } if (GetPairedValue(group, "WP_BLASTER", readbuf)) { bs->botWeaponWeights[WP_BLASTER] = atoi(readbuf); } if (GetPairedValue(group, "WP_DISRUPTOR", readbuf)) { bs->botWeaponWeights[WP_DISRUPTOR] = atoi(readbuf); } if (GetPairedValue(group, "WP_BOWCASTER", readbuf)) { bs->botWeaponWeights[WP_BOWCASTER] = atoi(readbuf); } if (GetPairedValue(group, "WP_REPEATER", readbuf)) { bs->botWeaponWeights[WP_REPEATER] = atoi(readbuf); } if (GetPairedValue(group, "WP_DEMP2", readbuf)) { bs->botWeaponWeights[WP_DEMP2] = atoi(readbuf); } if (GetPairedValue(group, "WP_FLECHETTE", readbuf)) { bs->botWeaponWeights[WP_FLECHETTE] = atoi(readbuf); } if (GetPairedValue(group, "WP_ROCKET_LAUNCHER", readbuf)) { bs->botWeaponWeights[WP_ROCKET_LAUNCHER] = atoi(readbuf); } if (GetPairedValue(group, "WP_THERMAL", readbuf)) { bs->botWeaponWeights[WP_THERMAL] = atoi(readbuf); } if (GetPairedValue(group, "WP_TRIP_MINE", readbuf)) { bs->botWeaponWeights[WP_TRIP_MINE] = atoi(readbuf); } if (GetPairedValue(group, "WP_DET_PACK", readbuf)) { bs->botWeaponWeights[WP_DET_PACK] = atoi(readbuf); } } bs->lovednum = 0; if (GetValueGroup(buf, "EmotionalAttachments", group)) { ParseEmotionalAttachments(bs, group); } B_TempFree(131072); //buf B_TempFree(1024); //readbuf B_TempFree(65536); //group trap_FS_FCloseFile(f); }
/* ====================== CG_ParseBuildableAnimationFile Read a configuration file containing animation counts and rates models/buildables/hivemind/animation.cfg, etc ====================== */ static qboolean CG_ParseBuildableAnimationFile( const char *filename, buildable_t buildable ) { char *text_p; int len; int i; char *token; float fps; char text[ 20000 ]; fileHandle_t f; animation_t *animations; animations = cg_buildables[ buildable ].animations; // load the file len = trap_FS_FOpenFile( filename, &f, FS_READ ); if( len <= 0 ) return qfalse; if( len >= sizeof( text ) - 1 ) { CG_Printf( "File %s too long\n", filename ); return qfalse; } trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); // parse the text text_p = text; // read information for each frame for( i = BANIM_NONE + 1; i < MAX_BUILDABLE_ANIMATIONS; i++ ) { token = COM_Parse( &text_p ); if( !*token ) break; animations[ i ].firstFrame = atoi( token ); token = COM_Parse( &text_p ); if( !*token ) break; animations[ i ].numFrames = atoi( token ); animations[ i ].reversed = qfalse; animations[ i ].flipflop = qfalse; // if numFrames is negative the animation is reversed if( animations[ i ].numFrames < 0 ) { animations[ i ].numFrames = -animations[ i ].numFrames; animations[ i ].reversed = qtrue; } token = COM_Parse( &text_p ); if ( !*token ) break; animations[i].loopFrames = atoi( token ); token = COM_Parse( &text_p ); if( !*token ) break; fps = atof( token ); if( fps == 0 ) fps = 1; animations[ i ].frameLerp = 1000 / fps; animations[ i ].initialLerp = 1000 / fps; } if( i != MAX_BUILDABLE_ANIMATIONS ) { CG_Printf( "Error parsing animation file: %s\n", filename ); return qfalse; } return qtrue; }
/* ====================== UI_ParseAnimationFile ====================== */ static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) { char *text_p, *prev; int len; int i; char *token; float fps; int skip; char text[20000]; fileHandle_t f; memset( animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS ); // load the file len = trap_FS_FOpenFile( filename, &f, FS_READ ); if ( len <= 0 ) { return qfalse; } if ( len >= ( sizeof( text ) - 1 ) ) { Com_Printf( "File %s too long\n", filename ); trap_FS_FCloseFile( f ); return qfalse; } trap_FS_Read( text, len, f ); text[len] = 0; trap_FS_FCloseFile( f ); COM_Compress(text); // parse the text text_p = text; skip = 0; // quite the compiler warning // read optional parameters while ( 1 ) { prev = text_p; // so we can unget token = COM_Parse( &text_p ); if ( !token ) { break; } if ( !Q_stricmp( token, "footsteps" ) ) { token = COM_Parse( &text_p ); if ( !token ) { break; } continue; } else if ( !Q_stricmp( token, "headoffset" ) ) { for ( i = 0 ; i < 3 ; i++ ) { token = COM_Parse( &text_p ); if ( !token ) { break; } } continue; } else if ( !Q_stricmp( token, "sex" ) ) { token = COM_Parse( &text_p ); if ( !token ) { break; } continue; } // if it is a number, start parsing animations if ( token[0] >= '0' && token[0] <= '9' ) { text_p = prev; // unget the token break; } Com_Printf( "unknown token '%s' is %s\n", token, filename ); } // read information for each frame for ( i = 0 ; i < MAX_ANIMATIONS ; i++ ) { token = COM_Parse( &text_p ); if ( !token ) { break; } animations[i].firstFrame = atoi( token ); // leg only frames are adjusted to not count the upper body only frames if ( i == LEGS_WALKCR ) { skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame; } if ( i >= LEGS_WALKCR ) { animations[i].firstFrame -= skip; } token = COM_Parse( &text_p ); if ( !token ) { break; } animations[i].numFrames = atoi( token ); token = COM_Parse( &text_p ); if ( !token ) { break; } animations[i].loopFrames = atoi( token ); token = COM_Parse( &text_p ); if ( !token ) { break; } fps = atof( token ); if ( fps == 0 ) { fps = 1; } animations[i].frameLerp = 1000 / fps; animations[i].initialLerp = 1000 / fps; } if ( i != MAX_ANIMATIONS ) { Com_Printf( "Error parsing animation file: %s\n", filename ); return qfalse; } return qtrue; }
/* ======================= UI_CalcPostGameStats ======================= */ static void UI_CalcPostGameStats() { char map[MAX_QPATH]; char fileName[MAX_QPATH]; char info[MAX_INFO_STRING]; fileHandle_t f; int size, game, time, adjustedTime; postGameInfo_t oldInfo; postGameInfo_t newInfo; qboolean newHigh = qfalse; trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) ); game = atoi(Info_ValueForKey(info, "g_gametype")); // compose file name Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game); // see if we have one already memset(&oldInfo, 0, sizeof(postGameInfo_t)); if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) { // if so load it size = 0; trap_FS_Read(&size, sizeof(int), f); if (size == sizeof(postGameInfo_t)) { trap_FS_Read(&oldInfo, sizeof(postGameInfo_t), f); } trap_FS_FCloseFile(f); } newInfo.accuracy = atoi(UI_Argv(3)); newInfo.impressives = atoi(UI_Argv(4)); newInfo.excellents = atoi(UI_Argv(5)); newInfo.defends = atoi(UI_Argv(6)); newInfo.assists = atoi(UI_Argv(7)); newInfo.gauntlets = atoi(UI_Argv(8)); newInfo.baseScore = atoi(UI_Argv(9)); newInfo.perfects = atoi(UI_Argv(10)); newInfo.redScore = atoi(UI_Argv(11)); newInfo.blueScore = atoi(UI_Argv(12)); time = atoi(UI_Argv(13)); newInfo.captures = atoi(UI_Argv(14)); newInfo.time = (time - trap_Cvar_VariableValue("ui_matchStartTime")) / 1000; adjustedTime = uiInfo.mapList[ui_currentMap.integer].timeToBeat[game]; if (newInfo.time < adjustedTime) { newInfo.timeBonus = (adjustedTime - newInfo.time) * 10; } else { newInfo.timeBonus = 0; } if (newInfo.redScore > newInfo.blueScore && newInfo.blueScore <= 0) { newInfo.shutoutBonus = 100; } else { newInfo.shutoutBonus = 0; } newInfo.skillBonus = trap_Cvar_VariableValue("g_spSkill"); if (newInfo.skillBonus <= 0) { newInfo.skillBonus = 1; } newInfo.score = newInfo.baseScore + newInfo.shutoutBonus + newInfo.timeBonus; newInfo.score *= newInfo.skillBonus; // see if the score is higher for this one newHigh = (newInfo.redScore > newInfo.blueScore && newInfo.score > oldInfo.score); if (newHigh) { // if so write out the new one uiInfo.newHighScoreTime = uiInfo.uiDC.realTime + 20000; if (trap_FS_FOpenFile(fileName, &f, FS_WRITE) >= 0) { size = sizeof(postGameInfo_t); trap_FS_Write(&size, sizeof(int), f); trap_FS_Write(&newInfo, sizeof(postGameInfo_t), f); trap_FS_FCloseFile(f); } } if (newInfo.time < oldInfo.time) { uiInfo.newBestTime = uiInfo.uiDC.realTime + 20000; } // put back all the ui overrides trap_Cvar_Set("capturelimit", UI_Cvar_VariableString("ui_saveCaptureLimit")); trap_Cvar_Set("fraglimit", UI_Cvar_VariableString("ui_saveFragLimit")); trap_Cvar_Set("duel_fraglimit", UI_Cvar_VariableString("ui_saveDuelLimit")); trap_Cvar_Set("cg_drawTimer", UI_Cvar_VariableString("ui_drawTimer")); trap_Cvar_Set("g_doWarmup", UI_Cvar_VariableString("ui_doWarmup")); trap_Cvar_Set("g_Warmup", UI_Cvar_VariableString("ui_Warmup")); trap_Cvar_Set("sv_pure", UI_Cvar_VariableString("ui_pure")); trap_Cvar_Set("g_friendlyFire", UI_Cvar_VariableString("ui_friendlyFire")); UI_SetBestScores(&newInfo, qtrue); UI_ShowPostGame(newHigh); }
/* =============== CG_ParseTrailFile Load the trail systems from a trail file =============== */ static bool CG_ParseTrailFile( const char *fileName ) { char *text_p; int i; int len; char *token; char text[ 32000 ]; char tsName[ MAX_QPATH ]; bool tsNameSet = false; fileHandle_t f; // load the file len = trap_FS_FOpenFile( fileName, &f, FS_READ ); if( len <= 0 ) return false; if( len >= sizeof( text ) - 1 ) { CG_Printf( S_COLOR_RED "ERROR: trail file %s too long\n", fileName ); return false; } trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); // parse the text text_p = text; // read optional parameters while( 1 ) { token = COM_Parse( &text_p ); if( !Q_stricmp( token, "" ) ) break; if( !Q_stricmp( token, "{" ) ) { if( tsNameSet ) { //check for name space clashes for( i = 0; i < numBaseTrailSystems; i++ ) { if( !Q_stricmp( baseTrailSystems[ i ].name, tsName ) ) { CG_Printf( S_COLOR_RED "ERROR: a trail system is already named %s\n", tsName ); return false; } } Q_strncpyz( baseTrailSystems[ numBaseTrailSystems ].name, tsName, MAX_QPATH ); if( !CG_ParseTrailSystem( &baseTrailSystems[ numBaseTrailSystems ], &text_p, tsName ) ) { CG_Printf( S_COLOR_RED "ERROR: %s: failed to parse trail system %s\n", fileName, tsName ); return false; } //start parsing trail systems again tsNameSet = false; if( numBaseTrailSystems == MAX_BASETRAIL_SYSTEMS ) { CG_Printf( S_COLOR_RED "ERROR: maximum number of trail systems (%d) reached\n", MAX_BASETRAIL_SYSTEMS ); return false; } else numBaseTrailSystems++; continue; } else { CG_Printf( S_COLOR_RED "ERROR: unamed trail system\n" ); return false; } } if( !tsNameSet ) { Q_strncpyz( tsName, token, sizeof( tsName ) ); tsNameSet = true; } else { CG_Printf( S_COLOR_RED "ERROR: trail system already named\n" ); return false; } } return true; }
/* ================== getCustomVote *Returns a custom vote. This will go beyond MAX_CUSTOM_VOTES. ================== */ t_customvote getCustomVote(char* votecommand) { t_customvote result; fileHandle_t file; char buffer[4*1024]; char *token,*pointer; char key[MAX_TOKEN_CHARS]; trap_FS_FOpenFile(g_votecustom.string,&file,FS_READ); if(!file) { memset(&result,0,sizeof(result)); return result; } memset(&buffer,0,sizeof(buffer)); trap_FS_Read(&buffer,sizeof(buffer),file); pointer = buffer; while ( qtrue ) { token = COM_Parse( &pointer ); if ( !token[0] ) { break; } if ( strcmp( token, "{" ) ) { Com_Printf( "Missing { in votecustom.cfg\n" ); break; } memset(&result,0,sizeof(result)); while ( 1 ) { token = COM_ParseExt( &pointer, qtrue ); if ( !token[0] ) { Com_Printf( "Unexpected end of customvote.cfg\n" ); break; } if ( !strcmp( token, "}" ) ) { break; } Q_strncpyz( key, token, sizeof( key ) ); token = COM_ParseExt( &pointer, qfalse ); if ( !token[0] ) { Com_Printf("Invalid/missing argument to %s in customvote.cfg\n",key); } if(!Q_stricmp(key,"votecommand")) { Q_strncpyz(result.votename,token,sizeof(result.votename)); } else if(!Q_stricmp(key,"displayname")) { Q_strncpyz(result.displayname,token,sizeof(result.displayname)); } else if(!Q_stricmp(key,"command")) { Q_strncpyz(result.command,token,sizeof(result.command)); } else { Com_Printf("Unknown key in customvote.cfg: %s\n",key); } } if(!Q_stricmp(result.votename,votecommand)) { return result; } } //Nothing was found memset(&result,0,sizeof(result)); return result; }
qboolean LoadLuaFile(char *path, int num_vm, vmType_t type) { int flen = 0; char *code; //char *signature; fileHandle_t f; lua_vm_t *vm; // try to open lua file flen = trap_FS_FOpenFile(path, &f, FS_READ); if(flen < 0) { LOG("Lua API: can not open file %s\n", path); trap_FS_FCloseFile(f); return qfalse; } else if(flen > LUA_MAX_FSIZE) { // quad: Let's not load arbitrarily big files to memory. // If your lua file exceeds the limit, let me know. LOG("Lua API: ignoring file %s (too big)\n", path); trap_FS_FCloseFile(f); return qfalse; } else { code = malloc(flen + 1); trap_FS_Read(code, flen, f); *(code + flen) = '\0'; trap_FS_FCloseFile(f); //signature = sha1(code); /* if ( Q_stricmp(lua_allowedModules.string, "") && !strstr(lua_allowedModules.string, signature) ) { // don't load disallowed lua modules into vm LOG("Lua API: Lua module [%s] [%s] disallowed by ACL\n", crt, signature); } else { */ // Init lua_vm_t struct vm = (lua_vm_t *) malloc(sizeof(lua_vm_t)); if(vm == NULL) { LOG("Lua API: failed to allocate memory for lua VM\n", path); return qfalse; } memset(vm, 0, sizeof(lua_vm_t)); vm->id = -1; Q_strncpyz(vm->file_name, path, sizeof(vm->file_name)); Q_strncpyz(vm->mod_name, "", sizeof(vm->mod_name)); Q_strncpyz(vm->mod_signature, "", sizeof(vm->mod_signature)); //Q_strncpyz(vm->mod_signature, signature, sizeof(vm->mod_signature)); vm->code = code; vm->code_size = flen; vm->type = type; vm->err = 0; // Start lua virtual machine if(G_LuaStartVM(vm) == qfalse) { G_LuaStopVM(vm); vm = NULL; return qfalse; } else { vm->id = num_vm; lVM[num_vm] = vm; return qtrue; } /* } */ } return qfalse; }
qboolean BG_LoadTraceMap(char *rawmapname, vec2_t world_mins, vec2_t world_maxs) { int i, j; fileHandle_t f; byte data, datablock[TRACEMAP_SIZE][4]; int sky_min, sky_max; int ground_min, ground_max; int skyground_min, skyground_max; float scalefactor; //int startTime = trap_Milliseconds(); ground_min = ground_max = MIN_WORLD_HEIGHT; skyground_min = skyground_max = MAX_WORLD_HEIGHT; sky_min = sky_max = MAX_WORLD_HEIGHT; if (trap_FS_FOpenFile(va("maps/%s_tracemap.tga", Q_strlwr(rawmapname)), &f, FS_READ) >= 0) { // skip over header for (i = 0; i < 18; i++) { trap_FS_Read(&data, 1, f); } for (i = 0; i < TRACEMAP_SIZE; i++) { trap_FS_Read(&datablock, sizeof(datablock), f); // TRACEMAP_SIZE * { b g r a } for (j = 0; j < TRACEMAP_SIZE; j++) { if (i == 0 && j < 6) { // abuse first six pixels for our extended data switch (j) { case 0: ground_min = datablock[j][0] | (datablock[j][1] << 8) | (datablock[j][2] << 16) | (datablock[j][3] << 24); break; case 1: ground_max = datablock[j][0] | (datablock[j][1] << 8) | (datablock[j][2] << 16) | (datablock[j][3] << 24); break; case 2: skyground_min = datablock[j][0] | (datablock[j][1] << 8) | (datablock[j][2] << 16) | (datablock[j][3] << 24); break; case 3: skyground_max = datablock[j][0] | (datablock[j][1] << 8) | (datablock[j][2] << 16) | (datablock[j][3] << 24); break; case 4: sky_min = datablock[j][0] | (datablock[j][1] << 8) | (datablock[j][2] << 16) | (datablock[j][3] << 24); break; case 5: sky_max = datablock[j][0] | (datablock[j][1] << 8) | (datablock[j][2] << 16) | (datablock[j][3] << 24); break; } tracemap.sky[TRACEMAP_SIZE - 1 - i][j] = MAX_WORLD_HEIGHT; tracemap.skyground[TRACEMAP_SIZE - 1 - i][j] = MAX_WORLD_HEIGHT; tracemap.ground[TRACEMAP_SIZE - 1 - i][j] = MIN_WORLD_HEIGHT; continue; } tracemap.sky[TRACEMAP_SIZE - 1 - i][j] = (float)datablock[j][0]; // FIXME: swap if (tracemap.sky[TRACEMAP_SIZE - 1 - i][j] == 0) { tracemap.sky[TRACEMAP_SIZE - 1 - i][j] = MAX_WORLD_HEIGHT; } tracemap.skyground[TRACEMAP_SIZE - 1 - i][j] = (float)datablock[j][1]; // FIXME: swap if (tracemap.skyground[TRACEMAP_SIZE - 1 - i][j] == 0) { tracemap.skyground[TRACEMAP_SIZE - 1 - i][j] = MAX_WORLD_HEIGHT; } tracemap.ground[TRACEMAP_SIZE - 1 - i][j] = (float)datablock[j][2]; // FIXME: swap if (tracemap.ground[TRACEMAP_SIZE - 1 - i][j] == 0) { tracemap.ground[TRACEMAP_SIZE - 1 - i][j] = MIN_WORLD_HEIGHT; } if (datablock[j][3] == 0) { // just in case tracemap.skyground[TRACEMAP_SIZE - 1 - i][j] = MAX_WORLD_HEIGHT; tracemap.ground[TRACEMAP_SIZE - 1 - i][j] = MIN_WORLD_HEIGHT; } } } trap_FS_FCloseFile(f); // Ground // calculate scalefactor if (ground_max - ground_min == 0) { scalefactor = 1.f; } else { // rain - scalefactor 254 to compensate for broken etmain behavior scalefactor = 254.f / (ground_max - ground_min); } // scale properly for (i = 0; i < TRACEMAP_SIZE; i++) { for (j = 0; j < TRACEMAP_SIZE; j++) { if (tracemap.ground[i][j] != MIN_WORLD_HEIGHT) { tracemap.ground[i][j] = ground_min + (tracemap.ground[i][j] / scalefactor); } } } // SkyGround // calculate scalefactor if (skyground_max - skyground_min == 0) { scalefactor = 1.f; } else { // rain - scalefactor 254 to compensate for broken etmain behavior scalefactor = 254.f / (skyground_max - skyground_min); } // scale properly for (i = 0; i < TRACEMAP_SIZE; i++) { for (j = 0; j < TRACEMAP_SIZE; j++) { if (tracemap.skyground[i][j] != MAX_WORLD_HEIGHT) { tracemap.skyground[i][j] = skyground_min + (tracemap.skyground[i][j] / scalefactor); } } } // Sky // calculate scalefactor if (sky_max - sky_min == 0) { scalefactor = 1.f; } else { // rain - scalefactor 254 to compensate for broken etmain behavior scalefactor = 254.f / (sky_max - sky_min); } // scale properly for (i = 0; i < TRACEMAP_SIZE; i++) { for (j = 0; j < TRACEMAP_SIZE; j++) { if (tracemap.sky[i][j] != MAX_WORLD_HEIGHT) { tracemap.sky[i][j] = sky_min + (tracemap.sky[i][j] / scalefactor); } } } } else { return(tracemap.loaded = qfalse); } tracemap.world_mins[0] = world_mins[0]; tracemap.world_mins[1] = world_mins[1]; tracemap.world_maxs[0] = world_maxs[0]; tracemap.world_maxs[1] = world_maxs[1]; one_over_mapgrid_factor[0] = 1.f / ((tracemap.world_maxs[0] - tracemap.world_mins[0]) / (float)TRACEMAP_SIZE); one_over_mapgrid_factor[1] = 1.f / ((tracemap.world_maxs[1] - tracemap.world_mins[1]) / (float)TRACEMAP_SIZE); tracemap.groundfloor = ground_min; tracemap.groundceil = ground_max; return(tracemap.loaded = qtrue); }
//=========================================================================== // Routine : AOTCTC_Holocron_Loadpositions // Description : Loads holocron positions from .hpf file on disk void AOTCTC_Holocron_Loadpositions( void ) {// Does each online player's data. char *s, *t; int len; fileHandle_t f; char *buf; //[DynamicMemoryTweaks] char loadPath[MAX_QPATH]; //[/DynamicMemoryTweaks] int statnum = 0; float stats[50*3]; // 1 extra. int holocron_number = 0; vmCvar_t mapname; G_Printf("^5Loading holocron position table..."); //loadPath = (char *)B_TempAlloc(1024*4); trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM ); Com_sprintf(loadPath, 1024*4, "holocron_positions/%s.hpf\0", mapname.string); len = trap_FS_FOpenFile( loadPath, &f, FS_READ ); if ( !f ) { G_Printf(" ^3FAILED!!!\n"); G_Printf("^5No file exists! (^3%s^5)\n", loadPath); return; } if ( !len ) { //empty file G_Printf(" ^3FAILED!!!\n"); G_Printf("^5Empty file!\n"); trap_FS_FCloseFile( f ); return; } if ( (buf = BG_TempAlloc(len+1)) == 0 ) {//alloc memory for buffer G_Printf(" ^3FAILED!!!\n"); G_Printf("^5Unable to allocate buffer.\n"); return; } trap_FS_Read( buf, len, f ); trap_FS_FCloseFile( f ); for (t = s = buf; *t;) { s = strchr(s, ' '); if (!s) break; while (*s == ' ') *s++ = 0; if (*t) { if (statnum == 0) { number_of_holocronpositions = atoi(t); if (number_of_holocronpositions <= 15) { G_Printf(" ^3FAILED!!!\n"); G_Printf("^5You need at least 16 holocron points!\n"); return; } } stats[statnum] = (float)atof(t); statnum++; } t = s; } statnum = 1; while (holocron_number < number_of_holocronpositions) { int reference = 0; while (reference <= 2) { holocrons[holocron_number].origin[reference] = stats[statnum]; statnum++; reference++; } holocron_number++; } BG_TempFree(len+1); G_Printf(" ^3Completed OK.\n"); G_Printf("^5Total Holocron Positions: ^7%i^5.\n", number_of_holocronpositions); holocrons_loaded = qtrue; }
void BG_SiegeParseClassFile(const char *filename, siegeClassDesc_t *descBuffer) { fileHandle_t f; int len; int i; char classInfo[4096]; char parseBuf[4096]; len = trap_FS_FOpenFile(filename, &f, FS_READ); if (!f || len >= 4096) { return; } trap_FS_Read(classInfo, len, f); trap_FS_FCloseFile(f); classInfo[len] = 0; //first get the description if we have a buffer for it if (descBuffer) { if (!BG_SiegeGetPairedValue(classInfo, "description", descBuffer->desc)) { strcpy(descBuffer->desc, "DESCRIPTION UNAVAILABLE"); } //Hit this assert? Memory has already been trashed. Increase //SIEGE_CLASS_DESC_LEN. assert(strlen(descBuffer->desc) < SIEGE_CLASS_DESC_LEN); } BG_SiegeGetValueGroup(classInfo, "ClassInfo", classInfo); //Parse name if (BG_SiegeGetPairedValue(classInfo, "name", parseBuf)) { strcpy(bgSiegeClasses[bgNumSiegeClasses].name, parseBuf); } else { Com_Error(ERR_DROP, "Siege class without name entry"); } //Parse forced model if (BG_SiegeGetPairedValue(classInfo, "model", parseBuf)) { strcpy(bgSiegeClasses[bgNumSiegeClasses].forcedModel, parseBuf); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].forcedModel[0] = 0; } //Parse forced skin if (BG_SiegeGetPairedValue(classInfo, "skin", parseBuf)) { strcpy(bgSiegeClasses[bgNumSiegeClasses].forcedSkin, parseBuf); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].forcedSkin[0] = 0; } //Parse first saber if (BG_SiegeGetPairedValue(classInfo, "saber1", parseBuf)) { strcpy(bgSiegeClasses[bgNumSiegeClasses].saber1, parseBuf); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saber1[0] = 0; } //Parse second saber if (BG_SiegeGetPairedValue(classInfo, "saber2", parseBuf)) { strcpy(bgSiegeClasses[bgNumSiegeClasses].saber2, parseBuf); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saber2[0] = 0; } //Parse forced saber stance if (BG_SiegeGetPairedValue(classInfo, "saberstyle", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].saberStance = BG_SiegeTranslateGenericTable(parseBuf, StanceTable, qtrue); } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].saberStance = 0; } //Parse forced saber color if (BG_SiegeGetPairedValue(classInfo, "sabercolor", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].forcedSaberColor = atoi(parseBuf); bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qtrue; } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qfalse; } //Parse forced saber2 color if (BG_SiegeGetPairedValue(classInfo, "saber2color", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].forcedSaber2Color = atoi(parseBuf); bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qtrue; } else { //It's ok if there isn't one, it's optional. bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qfalse; } //Parse weapons if (BG_SiegeGetPairedValue(classInfo, "weapons", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].weapons = BG_SiegeTranslateGenericTable(parseBuf, WPTable, qtrue); } else { Com_Error(ERR_DROP, "Siege class without weapons entry"); } if (!(bgSiegeClasses[bgNumSiegeClasses].weapons & (1 << WP_SABER))) { //make sure it has melee if there's no saber bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_MELEE); //always give them this too if they are not a saber user //bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_BRYAR_PISTOL); } //Parse forcepowers if (BG_SiegeGetPairedValue(classInfo, "forcepowers", parseBuf)) { BG_SiegeTranslateForcePowers(parseBuf, &bgSiegeClasses[bgNumSiegeClasses]); } else { //fine, clear out the powers. i = 0; while (i < NUM_FORCE_POWERS) { bgSiegeClasses[bgNumSiegeClasses].forcePowerLevels[i] = 0; i++; } } //Parse classflags if (BG_SiegeGetPairedValue(classInfo, "classflags", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].classflags = BG_SiegeTranslateGenericTable(parseBuf, bgSiegeClassFlagNames, qtrue); } else { //fine, we'll 0 it. bgSiegeClasses[bgNumSiegeClasses].classflags = 0; } //Parse maxhealth if (BG_SiegeGetPairedValue(classInfo, "maxhealth", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].maxhealth = atoi(parseBuf); } else { //It's alright, just default to 100 then. bgSiegeClasses[bgNumSiegeClasses].maxhealth = 100; } //Parse starthealth if (BG_SiegeGetPairedValue(classInfo, "starthealth", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].starthealth = atoi(parseBuf); } else { //It's alright, just default to 100 then. bgSiegeClasses[bgNumSiegeClasses].starthealth = bgSiegeClasses[bgNumSiegeClasses].maxhealth; } //Parse startarmor if (BG_SiegeGetPairedValue(classInfo, "maxarmor", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].maxarmor = atoi(parseBuf); } else { //It's alright, just default to 0 then. bgSiegeClasses[bgNumSiegeClasses].maxarmor = 0; } //Parse startarmor if (BG_SiegeGetPairedValue(classInfo, "startarmor", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].startarmor = atoi(parseBuf); if (!bgSiegeClasses[bgNumSiegeClasses].maxarmor) { //if they didn't specify a damn max armor then use this. bgSiegeClasses[bgNumSiegeClasses].maxarmor = bgSiegeClasses[bgNumSiegeClasses].startarmor; } } else { //default to maxarmor. bgSiegeClasses[bgNumSiegeClasses].startarmor = bgSiegeClasses[bgNumSiegeClasses].maxarmor; } //Parse speed (this is a multiplier value) if (BG_SiegeGetPairedValue(classInfo, "speed", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].speed = atof(parseBuf); } else { //It's alright, just default to 1 then. bgSiegeClasses[bgNumSiegeClasses].speed = 1.0f; } //Parse shader for ui to use if (BG_SiegeGetPairedValue(classInfo, "uishader", parseBuf)) { #ifdef QAGAME bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0; memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait)); #elif defined CGAME bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0; memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait)); #else //ui bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = trap_R_RegisterShaderNoMip(parseBuf); memcpy(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,parseBuf,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait)); #endif } else { //I guess this is an essential.. we don't want to render bad shaders or anything. Com_Error(ERR_DROP, "Siege class without uishader entry"); } //Parse shader for ui to use if (BG_SiegeGetPairedValue(classInfo, "class_shader", parseBuf)) { #ifdef QAGAME bgSiegeClasses[bgNumSiegeClasses].classShader = 0; #else //cgame, ui bgSiegeClasses[bgNumSiegeClasses].classShader = trap_R_RegisterShaderNoMip(parseBuf); assert( bgSiegeClasses[bgNumSiegeClasses].classShader ); if ( !bgSiegeClasses[bgNumSiegeClasses].classShader ) { //Com_Error( ERR_DROP, "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name ); Com_Printf( "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name ); } // A very hacky way to determine class . . . else #endif { // Find the base player class based on the icon name - very bad, I know. int titleLength, arrayTitleLength; char *holdBuf; titleLength = strlen(parseBuf); for (i=0;i<SPC_MAX;i++) { // Back up arrayTitleLength = strlen(classTitles[i]); if (arrayTitleLength>titleLength) // Too long { break; } holdBuf = parseBuf + ( titleLength - arrayTitleLength); if (!strcmp(holdBuf,classTitles[i])) { bgSiegeClasses[bgNumSiegeClasses].playerClass = i; break; } } // In case the icon name doesn't match up if (i>=SPC_MAX) { bgSiegeClasses[bgNumSiegeClasses].playerClass = SPC_INFANTRY; } } } else { //No entry! Bad bad bad //Com_Error( ERR_DROP, "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name ); Com_Printf( "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name ); } //Parse holdable items to use if (BG_SiegeGetPairedValue(classInfo, "holdables", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].invenItems = BG_SiegeTranslateGenericTable(parseBuf, HoldableTable, qtrue); } else { //Just don't start out with any then. bgSiegeClasses[bgNumSiegeClasses].invenItems = 0; } //Parse powerups to use if (BG_SiegeGetPairedValue(classInfo, "powerups", parseBuf)) { bgSiegeClasses[bgNumSiegeClasses].powerups = BG_SiegeTranslateGenericTable(parseBuf, PowerupTable, qtrue); } else { //Just don't start out with any then. bgSiegeClasses[bgNumSiegeClasses].powerups = 0; } //A successful read. bgNumSiegeClasses++; }
void BotUtilizePersonality(bot_state_t *bs) { fileHandle_t f; int len, rlen; int failed; int i; //char buf[131072]; char *buf = (char *)B_TempAlloc(131072); char *readbuf, *group; len = trap_FS_FOpenFile(bs->settings.personalityfile, &f, FS_READ); failed = 0; if (!f) { G_Printf(S_COLOR_RED "Error: Specified personality not found\n"); B_TempFree(131072); //buf return; } if (len >= 131072) { G_Printf(S_COLOR_RED "Personality file exceeds maximum length\n"); trap_FS_FCloseFile(f);//[TicketFix143] B_TempFree(131072); //buf return; } trap_FS_Read(buf, len, f); rlen = len; while (len < 131072) { //kill all characters after the file length, since sometimes FS_Read doesn't do that entirely (or so it seems) buf[len] = '\0'; len++; } len = rlen; readbuf = (char *)B_TempAlloc(1024); group = (char *)B_TempAlloc(65536); if (!GetValueGroup(buf, "GeneralBotInfo", group)) { G_Printf(S_COLOR_RED "Personality file contains no GeneralBotInfo group\n"); failed = 1; //set failed so we know to set everything to default values } if (!failed && GetPairedValue(group, "reflex", readbuf)) { bs->skills.reflex = atoi(readbuf); } else { bs->skills.reflex = 100; //default } if (!failed && GetPairedValue(group, "accuracy", readbuf)) { bs->skills.accuracy = atof(readbuf); } else { bs->skills.accuracy = 10; //default } if (!failed && GetPairedValue(group, "turnspeed", readbuf)) { bs->skills.turnspeed = atof(readbuf); } else { bs->skills.turnspeed = 0.01f; //default } if (!failed && GetPairedValue(group, "turnspeed_combat", readbuf)) { bs->skills.turnspeed_combat = atof(readbuf); } else { bs->skills.turnspeed_combat = 0.05f; //default } if (!failed && GetPairedValue(group, "maxturn", readbuf)) { bs->skills.maxturn = atof(readbuf); } else { bs->skills.maxturn = 360; //default } if (!failed && GetPairedValue(group, "perfectaim", readbuf)) { bs->skills.perfectaim = atoi(readbuf); } else { bs->skills.perfectaim = 0; //default } if (!failed && GetPairedValue(group, "chatability", readbuf)) { bs->canChat = atoi(readbuf); } else { bs->canChat = 0; //default } if (!failed && GetPairedValue(group, "chatfrequency", readbuf)) { bs->chatFrequency = atoi(readbuf); } else { bs->chatFrequency = 5; //default } if (!failed && GetPairedValue(group, "hatelevel", readbuf)) { bs->loved_death_thresh = atoi(readbuf); } else { bs->loved_death_thresh = 3; //default } if (!failed && GetPairedValue(group, "camper", readbuf)) { bs->isCamper = atoi(readbuf); } else { bs->isCamper = 0; //default } if (!failed && GetPairedValue(group, "saberspecialist", readbuf)) { bs->saberSpecialist = atoi(readbuf); } else { bs->saberSpecialist = 0; //default } if (!failed && GetPairedValue(group, "forceinfo", readbuf)) { Com_sprintf(bs->forceinfo, sizeof(bs->forceinfo), "%s\0", readbuf); } else { Com_sprintf(bs->forceinfo, sizeof(bs->forceinfo), "%s\0", DEFAULT_FORCEPOWERS); } //[ExpSys] //boost size of forceinfo to match the current number of skills (backwards compatibility thingy) if( strlen(bs->forceinfo) < (NUM_TOTAL_SKILLS + 4) ) {//forceinfo isn't long enough, boost the size... for(i=NUM_FORCE_POWERS+4; i < (NUM_TOTAL_SKILLS + 4); i++) { if(bs->forceinfo[i] < '0' || bs->forceinfo[i] > '3') {//bad value, reset bs->forceinfo[i] = '0'; } } bs->forceinfo[NUM_TOTAL_SKILLS + 4 + 1] = '\0'; } i = 4; for(i = 4; (i - 4) < NUM_FORCE_POWERS; i++) { if(bs->forceinfo[i] != '0') {//bot is using force power, make sure that they have at least one rank of force seeing if(bs->forceinfo[FP_SEE + 4] == '0') {//bot file doesn't normally have force seeing, give them some bs->forceinfo[FP_SEE + 4] = '1'; } } } //[/ExpSys] //[StanceSelection] //add stance skills for Bots if(bs->forceinfo[FP_SABER_OFFENSE + 4] > 0) { int count; //just bump all the NPC's other saber styles to their saber offense skill level for(count = SK_BLUESTYLE; count <= SK_STAFFSTYLE; count++) { bs->forceinfo[NUM_FORCE_POWERS + count + 4] = bs->forceinfo[FP_SABER_OFFENSE + 4]; } } //[/StanceSelection] i = 0; while (i < MAX_CHAT_BUFFER_SIZE) { //clear out the chat buffer for this bot gBotChatBuffer[bs->client][i] = '\0'; i++; } if (bs->canChat) { if (!ReadChatGroups(bs, buf)) { bs->canChat = 0; } } if (GetValueGroup(buf, "BotWeaponWeights", group)) { if (GetPairedValue(group, "WP_STUN_BATON", readbuf)) { bs->botWeaponWeights[WP_STUN_BATON] = atoi(readbuf); bs->botWeaponWeights[WP_MELEE] = bs->botWeaponWeights[WP_STUN_BATON]; } if (GetPairedValue(group, "WP_SABER", readbuf)) { bs->botWeaponWeights[WP_SABER] = atoi(readbuf); } if (GetPairedValue(group, "WP_BRYAR_PISTOL", readbuf)) { bs->botWeaponWeights[WP_BRYAR_PISTOL] = atoi(readbuf); } if (GetPairedValue(group, "WP_BLASTER", readbuf)) { bs->botWeaponWeights[WP_BLASTER] = atoi(readbuf); } if (GetPairedValue(group, "WP_DISRUPTOR", readbuf)) { bs->botWeaponWeights[WP_DISRUPTOR] = atoi(readbuf); } if (GetPairedValue(group, "WP_BOWCASTER", readbuf)) { bs->botWeaponWeights[WP_BOWCASTER] = atoi(readbuf); } if (GetPairedValue(group, "WP_REPEATER", readbuf)) { bs->botWeaponWeights[WP_REPEATER] = atoi(readbuf); } if (GetPairedValue(group, "WP_DEMP2", readbuf)) { bs->botWeaponWeights[WP_DEMP2] = atoi(readbuf); } if (GetPairedValue(group, "WP_FLECHETTE", readbuf)) { bs->botWeaponWeights[WP_FLECHETTE] = atoi(readbuf); } if (GetPairedValue(group, "WP_ROCKET_LAUNCHER", readbuf)) { bs->botWeaponWeights[WP_ROCKET_LAUNCHER] = atoi(readbuf); } if (GetPairedValue(group, "WP_THERMAL", readbuf)) { bs->botWeaponWeights[WP_THERMAL] = atoi(readbuf); } if (GetPairedValue(group, "WP_TRIP_MINE", readbuf)) { bs->botWeaponWeights[WP_TRIP_MINE] = atoi(readbuf); } if (GetPairedValue(group, "WP_DET_PACK", readbuf)) { bs->botWeaponWeights[WP_DET_PACK] = atoi(readbuf); } } //[ExpSys] if(!bs->saberSpecialist) {//give bots weapon skills based on their weapon weights if they aren't a saber specialist. for(i=0; i < WP_NUM_WEAPONS; i++) { int skillLevel = FORCE_LEVEL_0; if(bs->botWeaponWeights[i] >= 11) {//master level skillLevel = FORCE_LEVEL_3; } else if(bs->botWeaponWeights[i] > 5) { skillLevel = FORCE_LEVEL_2; } else if(bs->botWeaponWeights[i] > 0) {//has weapon skillLevel = FORCE_LEVEL_1; } else {//don't want this weapon. continue; } switch(i) { case WP_BRYAR_PISTOL: bs->forceinfo[NUM_FORCE_POWERS+SK_PISTOL + 4] = '0' + skillLevel; break; case WP_BLASTER: bs->forceinfo[NUM_FORCE_POWERS+SK_BLASTER + 4] = '0' + skillLevel; break; case WP_DISRUPTOR: bs->forceinfo[NUM_FORCE_POWERS+SK_DISRUPTOR + 4] = '0' + skillLevel; break; case WP_BOWCASTER: bs->forceinfo[NUM_FORCE_POWERS+SK_BOWCASTER + 4] = '0' + skillLevel; break; case WP_REPEATER: bs->forceinfo[NUM_FORCE_POWERS+SK_REPEATER + 4] = '0' + skillLevel; break; case WP_ROCKET_LAUNCHER: bs->forceinfo[NUM_FORCE_POWERS+SK_ROCKET + 4] = '0' + skillLevel; break; case WP_THERMAL: bs->forceinfo[NUM_FORCE_POWERS+SK_THERMAL + 4] = '0' + skillLevel; break; case WP_DET_PACK: bs->forceinfo[NUM_FORCE_POWERS+SK_DETPACK + 4] = '0' + skillLevel; break; }; } } //[/ExpSys] bs->lovednum = 0; if (GetValueGroup(buf, "EmotionalAttachments", group)) { ParseEmotionalAttachments(bs, group); } B_TempFree(131072); //buf B_TempFree(1024); //readbuf B_TempFree(65536); //group trap_FS_FCloseFile(f); }
void G_xpsave_readconfig() { g_xpsave_t *x = g_xpsaves[0]; g_mapstat_t *m = g_mapstats[0]; int xc = 0; int mc = 0; fileHandle_t f; int i, j; int len; char *cnf, *cnf2; char *t; qboolean xpsave_open; qboolean mapstat_open; qboolean serverstat_open; qboolean found_serverstat = qfalse; float skill; char buffer[MAX_STRING_CHARS]; if(!(g_XPSave.integer & XPSF_ENABLE)) return; if(!g_XPSaveFile.string[0]) return; len = trap_FS_FOpenFile(g_XPSaveFile.string, &f, FS_READ) ; if(len < 0) { G_Printf("readconfig: could not open xpsave file %s\n", g_XPSaveFile.string); return; } cnf = malloc(len+1); cnf2 = cnf; trap_FS_Read(cnf, len, f); *(cnf + len) = '\0'; trap_FS_FCloseFile(f); G_xpsave_cleanup(); t = COM_Parse(&cnf); xpsave_open = qfalse; mapstat_open = qfalse; serverstat_open = qfalse; while(*t) { if(!Q_stricmp(t, "[xpsave]") || !Q_stricmp(t, "[mapstat]") || !Q_stricmp(t, "[serverstat]") ) { if(xpsave_open) g_xpsaves[xc++] = x; if(mapstat_open) g_mapstats[mc++] = m; xpsave_open = qfalse; mapstat_open = qfalse; serverstat_open = qfalse; } if(xpsave_open) { if(!Q_stricmp(t, "guid")) { G_shrubbot_readconfig_string(&cnf, x->guid, sizeof(x->guid)); } else if(!Q_stricmp(t, "name")) { G_shrubbot_readconfig_string(&cnf, x->name, sizeof(x->name)); } else if(!Q_stricmp(t, "time")) { G_shrubbot_readconfig_int(&cnf, &x->time); } else if(!Q_stricmpn(t, "skill[", 6)) { for(i=0; i<SK_NUM_SKILLS; i++) { if(Q_stricmp(t, va("skill[%i]", i))) continue; G_shrubbot_readconfig_float(&cnf, &skill); x->skill[i] = skill; break; } } else if(!Q_stricmp(t, "kill_rating")) { G_shrubbot_readconfig_float(&cnf, &x->kill_rating); } else if(!Q_stricmp(t, "kill_variance")) { G_shrubbot_readconfig_float(&cnf, &x->kill_variance); } else if(!Q_stricmp(t, "rating")) { G_shrubbot_readconfig_float(&cnf, &x->rating); } else if(!Q_stricmp(t, "rating_variance")) { G_shrubbot_readconfig_float(&cnf, &x->rating_variance); } else if(!Q_stricmp(t, "mutetime")) { G_shrubbot_readconfig_int(&cnf, &x->mutetime); } else if(!Q_stricmpn(t, "pr_skill[", 9)) { for(i=0; i<SK_NUM_SKILLS; i++) { if(Q_stricmp(t, va("pr_skill[%i]", i))) continue; G_shrubbot_readconfig_string(&cnf, buffer, sizeof(buffer)); sscanf(buffer, "%i %f %i %f %i %f %i %f %i %f", &x->pr_skill_updates[i][0], &x->pr_skill[i][0], &x->pr_skill_updates[i][1], &x->pr_skill[i][1], &x->pr_skill_updates[i][2], &x->pr_skill[i][2], &x->pr_skill_updates[i][3], &x->pr_skill[i][3], &x->pr_skill_updates[i][4], &x->pr_skill[i][4]); break; } } else { G_Printf("xpsave: [xpsave] parse error near " "%s on line %d\n", t, COM_GetCurrentParseLine()); } } else if(mapstat_open) { if(!Q_stricmp(t, "name")) { G_shrubbot_readconfig_string(&cnf, m->name, sizeof(m->name)); } else if(!Q_stricmp(t, "rating")) { G_shrubbot_readconfig_float(&cnf, &m->rating); } else if(!Q_stricmp(t, "rating_variance")) { G_shrubbot_readconfig_float(&cnf, &m->rating_variance); } else if(!Q_stricmp(t, "spree_record")) { G_shrubbot_readconfig_int(&cnf, &m->spreeRecord); } else if(!Q_stricmp(t, "spree_name")) { G_shrubbot_readconfig_string(&cnf, m->spreeName, sizeof(m->spreeName)); } else { G_Printf("xpsave: [mapstat] parse error near " "%s on line %d\n", t, COM_GetCurrentParseLine()); } } else if(serverstat_open) { if(!Q_stricmp(t, "rating")) { G_shrubbot_readconfig_float(&cnf, &g_serverstat.rating); } else if(!Q_stricmp(t, "rating_variance")) { G_shrubbot_readconfig_float(&cnf, &g_serverstat.rating_variance); } else if(!Q_stricmp(t, "distance_rating")) { G_shrubbot_readconfig_float(&cnf, &g_serverstat.distance_rating); } else if(!Q_stricmp(t, "distance_variance")) { G_shrubbot_readconfig_float(&cnf, &g_serverstat.distance_variance); } else { G_Printf("xpsave: [serverstat] parse error near " "%s on line %d\n", t, COM_GetCurrentParseLine()); } } if(!Q_stricmp(t, "[xpsave]")) { if(xc >= MAX_XPSAVES) { G_Printf("xpsave: error MAX_XPSAVES exceeded"); return; } x = malloc(sizeof(g_xpsave_t)); x->guid[0] = '\0'; x->name[0] = '\0'; x->kill_rating = 0.0f; x->kill_variance = SIGMA2_DELTA; x->rating = 0.0f; x->rating_variance = SIGMA2_THETA; for(i=0; i<SK_NUM_SKILLS; i++) { x->skill[i] = 0.0f; for(j=0; j<NUM_SKILL_LEVELS; j++) { x->pr_skill_updates[i][j] = 0; x->pr_skill[i][j] = 0.0f; } } x->mutetime = 0; x->hits = 0; x->team_hits = 0; x->time = 0; xpsave_open = qtrue; } if(!Q_stricmp(t, "[mapstat]")) { if(mc >= MAX_MAPSTATS) { G_Printf("xpsave: error MAX_MAPSTATS exceeded"); return; } m = malloc(sizeof(g_mapstat_t)); m->name[0] = '\0'; m->rating = 0.0f; m->rating_variance = SIGMA2_GAMMA; m->spreeRecord = 0; m->spreeName[0] = '\0'; mapstat_open = qtrue; } if(!Q_stricmp(t, "[serverstat]")) { // server prior = 2.6, NOT 0 g_serverstat.rating = 2.6f; g_serverstat.rating_variance = SIGMA2_PSI; g_serverstat.distance_rating = 0.0f; g_serverstat.distance_variance = SIGMA2_DELTA; serverstat_open = qtrue; found_serverstat = qtrue; } t = COM_Parse(&cnf); } if(xpsave_open) g_xpsaves[xc++] = x; else if(mapstat_open) g_mapstats[mc++] = m; free(cnf2); if (!found_serverstat) { // server prior = 2.6, NOT 0 g_serverstat.rating = 2.6f; g_serverstat.rating_variance = SIGMA2_PSI; } G_Printf("xpsave: loaded %d mapstats, %d xpsaves\n", mc, xc); }
static void G_AddBot( const char *name, int skill, const char *team, const char *spawnPoint, int playerClass, int playerWeapon, int characerIndex, const char *respawn, const char *scriptName, int rank, int skills[], qboolean pow ) { #define MAX_BOTNAMES 1024 int clientNum; char *botinfo; gentity_t *bot; char *key; char *s; char *botname; // char *model; char userinfo[MAX_INFO_STRING]; // get the botinfo from bots.txt botinfo = G_GetBotInfoByName( "wolfbot" ); if ( !botinfo ) { G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name ); return; } // create the bot's userinfo userinfo[0] = '\0'; botname = Info_ValueForKey( botinfo, "funname" ); if( !botname[0] ) { botname = Info_ValueForKey( botinfo, "name" ); } Info_SetValueForKey( userinfo, "name", botname ); Info_SetValueForKey( userinfo, "rate", "25000" ); Info_SetValueForKey( userinfo, "snaps", "20" ); Info_SetValueForKey( userinfo, "skill", va("%i", skill) ); s = Info_ValueForKey(botinfo, "aifile"); if (!*s ) { trap_Printf( S_COLOR_RED "Error: bot has no aifile specified\n" ); return; } // have the server allocate a client slot clientNum = trap_BotAllocateClient( 0 ); // Arnout: 0 means no prefered clientslot if ( clientNum == -1 ) { G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" ); G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" ); return; } // initialize the bot settings if( !team || !*team ) { if( PickTeam(clientNum) == TEAM_AXIS) { team = "red"; } else { team = "blue"; } } Info_SetValueForKey( userinfo, "characterfile", Info_ValueForKey( botinfo, "aifile" ) ); //Info_SetValueForKey( userinfo, "skill", va( "%i", skill ) ); Info_SetValueForKey( userinfo, "team", team ); if( spawnPoint && spawnPoint[0] ) { Info_SetValueForKey( userinfo, "spawnPoint", spawnPoint ); } if (scriptName && scriptName[0]) { Info_SetValueForKey( userinfo, "scriptName", scriptName ); } /* if (playerClass > 0) { Info_SetValueForKey( userinfo, "pClass", va("%i", playerClass) ); } if (playerWeapon) { Info_SetValueForKey( userinfo, "pWeapon", va("%i", playerWeapon) ); }*/ // END Mad Doc - TDF key = "wolfbot"; if (!Q_stricmp( (char *)name, key )) { // read the botnames file, and pick a name that doesnt exist fileHandle_t f; int len, i, j, k; qboolean setname = qfalse; char botnames[8192], *pbotnames, *listbotnames[MAX_BOTNAMES], *token, *oldpbotnames; int lengthbotnames[MAX_BOTNAMES]; len = trap_FS_FOpenFile( "botfiles/botnames.txt", &f, FS_READ ); if (len >= 0) { if (len > sizeof(botnames)) { G_Error( "botfiles/botnames.txt is too big (max = %i)", (int)sizeof(botnames) ); } memset( botnames, 0, sizeof(botnames) ); trap_FS_Read( botnames, len, f ); pbotnames = botnames; // read them in i = 0; oldpbotnames = pbotnames; while ((token = COM_Parse( &pbotnames ))) { if (!token[0]) break; listbotnames[i] = strstr( oldpbotnames, token ); lengthbotnames[i] = strlen(token); listbotnames[i][lengthbotnames[i]] = 0; oldpbotnames = pbotnames; if (++i == MAX_BOTNAMES) break; } // if (i > 2) { j = rand() % (i-1); // start at a random spot inthe list for( k = j + 1; k != j; k++ ) { if( k == i ) { k = -1; // gets increased on next loop continue; } if (ClientFromName( listbotnames[k] ) == -1) { // found an unused name Info_SetValueForKey( userinfo, "name", listbotnames[k] ); setname = qtrue; break; } } } // trap_FS_FCloseFile( f ); } if (!setname) { Info_SetValueForKey( userinfo, "name", va("wolfbot_%i", clientNum+1) ); } } else { Info_SetValueForKey( userinfo, "name", name ); } // if a character was specified, put the index of that character filename in the CS_CHARACTERS table in the userinfo if( characerIndex != -1 ) { Info_SetValueForKey( userinfo, "ch", va( "%i", characerIndex ) ); } // if a rank was specified, use that /* if (rank != -1) { Info_SetValueForKey(userinfo, "rank", va("%i", rank)); }*/ // END Mad Doc - TDF bot = &g_entities[ clientNum ]; bot->r.svFlags |= SVF_BOT; if( pow ) { bot->r.svFlags |= SVF_POW; } bot->inuse = qtrue; bot->aiName = bot->client->pers.netname; // register the userinfo trap_SetUserinfo( clientNum, userinfo ); // have it connect to the game as a normal client if ((s = ClientConnect( clientNum, qtrue, qtrue ))) { G_Printf( S_COLOR_RED "Unable to add bot: %s\n", s ); return; } SetTeam( bot, (char *)team, qtrue, -1, -1, qfalse ); /* if( skills ) { int i; for( i = 0; i < SK_NUM_SKILLS; i++ ) { bot->client->sess.skill[i] = skills[i]; } }*/ return; }
static size_t ovcb_read( void *ptr, size_t size, size_t nb, void *datasource ) { qintptr filenum = (qintptr) datasource; return trap_FS_Read( ptr, size * nb, (int) filenum ) / size; }
/* * CG_LoadRecamScriptFile */ bool CG_LoadRecamScriptFile( char *filename ) { int filelen, filehandle; qbyte *buf = NULL; char *ptr, *token; int linecount; cg_democam_t *cam = NULL; if( !filename ) { CG_Printf( "CG_LoadRecamScriptFile: no filename\n" ); return false; } filelen = trap_FS_FOpenFile( filename, &filehandle, FS_READ ); if( !filehandle || filelen < 1 ) { trap_FS_FCloseFile( filehandle ); } else { buf = ( qbyte * )CG_Malloc( filelen + 1 ); filelen = trap_FS_Read( buf, filelen, filehandle ); trap_FS_FCloseFile( filehandle ); } if( !buf ) return false; // parse the script linecount = 0; ptr = ( char * )buf; while( ptr ) { token = COM_ParseExt( &ptr, qtrue ); if( !token[0] ) break; if( !Q_stricmp( token, "subtitle" ) || !Q_stricmp( token, "print" ) ) { cg_subtitle_t *sub; sub = CG_Democam_RegisterSubtitle(); sub->highprint = ( Q_stricmp( token, "print" ) == 0 ); token = COM_ParseExt( &ptr, qtrue ); if( !token[0] ) break; sub->timeStamp = (unsigned int)atoi( token ); token = COM_ParseExt( &ptr, qtrue ); if( !token[0] ) break; sub->maxDuration = (unsigned int)atoi( token ); sub->text = CG_CopyString( COM_ParseExt( &ptr, qtrue ) ); linecount = 0; } else { switch( linecount ) { case 0: cam = CG_Democam_RegisterCam( atoi( token ) ); break; case 1: cam->timeStamp = (unsigned int)atoi( token ); break; case 2: cam->origin[0] = atof( token ); break; case 3: cam->origin[1] = atof( token ); break; case 4: cam->origin[2] = atof( token ); break; case 5: cam->angles[0] = atof( token ); break; case 6: cam->angles[1] = atof( token ); break; case 7: cam->angles[2] = atof( token ); break; case 8: cam->trackEnt = atoi( token ); break; case 9: cam->fov = atoi( token ); break; default: CG_Error( "CG_LoadRecamScriptFile: bad switch\n" ); } linecount++; if( linecount == 10 ) linecount = 0; } } CG_Free( buf ); if( linecount != 0 ) { CG_Printf( "CG_LoadRecamScriptFile: Invalid script. Ignored\n" ); CG_Democam_FreeCams(); CG_Democam_FreeSubtitles(); return false; } CG_Democam_ExecutePathAnalysis(); return true; }
qboolean G_ParseMapSettings(int handle, config_t *config) { pc_token_t token; char serverinfo[MAX_INFO_STRING]; char *mapname; trap_GetServerinfo(serverinfo, sizeof(serverinfo)); mapname = Info_ValueForKey(serverinfo, "mapname"); if (!trap_PC_ReadToken(handle, &token)) { G_Printf("Malformed map config\n"); } G_Printf("Map settings for: %s\n", token.string); G_Printf("Current map: %s\n", mapname); if (!Q_stricmp(token.string, "default")) { G_Printf("Setting rules for map: %s\n", token.string); return G_ParseSettings(handle, qtrue, config); } else if (!Q_stricmp(token.string, mapname)) { fileHandle_t f; char *code, *signature; qboolean res; G_Printf("Setting rules for map: %s\n", token.string); res = G_ParseSettings(handle, qtrue, config); if (res && strlen(config->mapscripthash)) { char sdir[MAX_QPATH]; int flen = 0; trap_Cvar_VariableStringBuffer("g_mapScriptDirectory", sdir, sizeof(sdir)); flen = trap_FS_FOpenFile(va("%s/%s.script", sdir, mapname), &f, FS_READ); if (flen < 0) { // FIXME: handle this properly.. //return G_ConfigError(handle, "Cannot open mapscript file for hash verification: %s/%s.script", sdir, mapname); G_Printf("Cannot open mapscript file for hash verification: %s/%s.script", sdir, mapname); return res; } code = malloc(flen + 1); trap_FS_Read(code, flen, f); *(code + flen) = '\0'; trap_FS_FCloseFile(f); signature = G_SHA1(code); free(code); if (Q_stricmp(config->mapscripthash, signature)) { return G_ConfigError(handle, "Invalid mapscript hash for map: %s hash given in config: \"%s\" scripts actual hash \"%s\"", mapname, config->mapscripthash, signature); } G_Printf("Hash is valid for map: %s\n", mapname); } return res; } else { G_Printf("Ignoring rules for map: %s\n", token.string); return G_ParseSettings(handle, qfalse, config); } }
/* =============== G_ParseMapRotationFile Load the map rotations from a map rotation file =============== */ static qboolean G_ParseMapRotationFile( const char *fileName ) { char *text_p; int i; int len; char *token; char text[ 20000 ]; char mrName[ MAX_QPATH ]; qboolean mrNameSet = qfalse; fileHandle_t f; // load the file len = trap_FS_FOpenFile( fileName, &f, FS_READ ); if( len <= 0 ) return qfalse; if( len >= sizeof( text ) - 1 ) { G_Printf( S_COLOR_RED "ERROR: map rotation file %s too long\n", fileName ); return qfalse; } trap_FS_Read( text, len, f ); text[ len ] = 0; trap_FS_FCloseFile( f ); // parse the text text_p = text; // read optional parameters while( 1 ) { token = COM_Parse( &text_p ); if( !token ) break; if( !Q_stricmp( token, "" ) ) break; if( !Q_stricmp( token, "{" ) ) { if( mrNameSet ) { //check for name space clashes for( i = 0; i < mapRotations.numRotations; i++ ) { if( !Q_stricmp( mapRotations.rotations[ i ].name, mrName ) ) { G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName ); return qfalse; } } Q_strncpyz( mapRotations.rotations[ mapRotations.numRotations ].name, mrName, MAX_QPATH ); if( !G_ParseMapRotation( &mapRotations.rotations[ mapRotations.numRotations ], &text_p ) ) { G_Printf( S_COLOR_RED "ERROR: %s: failed to parse map rotation %s\n", fileName, mrName ); return qfalse; } //start parsing particle systems again mrNameSet = qfalse; if( mapRotations.numRotations == MAX_MAP_ROTATIONS ) { G_Printf( S_COLOR_RED "ERROR: maximum number of map rotations (%d) reached\n", MAX_MAP_ROTATIONS ); return qfalse; } else mapRotations.numRotations++; continue; } else { G_Printf( S_COLOR_RED "ERROR: unamed map rotation\n" ); return qfalse; } } if( !mrNameSet ) { Q_strncpyz( mrName, token, sizeof( mrName ) ); mrNameSet = qtrue; } else { G_Printf( S_COLOR_RED "ERROR: map rotation already named\n" ); return qfalse; } } return qtrue; }