/* =============== 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; } } 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; } 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; } mapRotations.numRotations++; //start parsing map rotations again mrNameSet = qfalse; continue; } else { G_Printf( S_COLOR_RED "ERROR: unnamed 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; }
/* =============== G_ParseMapRotationFile Load the map rotations from a map rotation file =============== */ static qboolean G_ParseMapRotationFile( const char *fileName ) { char *text_p; int i, j; 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 if ( G_RotationExists( mrName ) ) { G_Printf( S_COLOR_RED "ERROR: a map rotation is already named %s\n", mrName ); return 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; } 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; } mapRotations.numRotations++; //start parsing map rotations again mrNameSet = qfalse; continue; } else { G_Printf( S_COLOR_RED "ERROR: unnamed 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++ ) { mapRotation_t *mr = &mapRotations.rotations[ i ]; int mapCount = 0; for ( j = 0; j < mr->numNodes; j++ ) { node_t *node = mr->nodes[ j ]; if ( node->type == NT_MAP ) { mapCount++; if ( !G_MapExists( node->u.map.name ) ) { G_Printf( S_COLOR_RED "ERROR: rotation map \"%s\" doesn't exist\n", node->u.map.name ); return qfalse; } continue; } else if ( node->type == NT_RETURN ) { continue; } else if ( node->type == NT_LABEL ) { continue; } else { while ( node->type == NT_CONDITION ) { node = node->u.condition.target; } } if ( ( node->type == NT_GOTO || node->type == NT_RESUME ) && !G_LabelExists( i, node->u.label.name ) && !G_RotationExists( node->u.label.name ) ) { G_Printf( S_COLOR_RED "ERROR: goto destination named \"%s\" doesn't exist\n", node->u.label.name ); return qfalse; } } if ( mapCount == 0 ) { G_Printf( S_COLOR_RED "ERROR: rotation \"%s\" needs at least one map entry\n", mr->name ); return qfalse; } } return qtrue; }