示例#1
0
/*
===============
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;
}
示例#2
0
/*
===============
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;
}
示例#3
0
/*
===============
G_PrintCurrentRotation

Print the current rotation to an entity
===============
*/
void G_PrintCurrentRotation( gentity_t *ent )
{
	int           mapRotationIndex = g_currentMapRotation.integer;
	mapRotation_t *mapRotation = G_MapRotationActive() ? &mapRotations.rotations[ mapRotationIndex ] : NULL;
	int           i = 0;
	char          currentMapName[ MAX_QPATH ];
	node_t        *node;

	if ( mapRotation == NULL )
	{
		trap_SendServerCommand( ent - g_entities, "print \"^3listrotation^3: ^7there is no active map rotation on this server\n\"" );
		return;
	}

	if ( mapRotation->numNodes == 0 )
	{
		trap_SendServerCommand( ent - g_entities, "print \"^3listrotation^3: ^7there are no maps in the active map rotation\n\"" );
		return;
	}

	trap_Cvar_VariableStringBuffer( "mapname", currentMapName, sizeof( currentMapName ) );

	ADMBP_begin();
	ADMBP( va( "%s:\n", mapRotation->name ) );

	while ( ( node = mapRotation->nodes[ i++ ] ) )
	{
		int  colour = 7;
		char *prefix;
		char *suffix = "";

		switch ( node->type )
		{
			case NT_RETURN:
				prefix = "return";
				break;

			case NT_LABEL:
				prefix = "label: ";
				break;

			case NT_GOTO:
				prefix = "goto: ";
				break;

			case NT_RESUME:
				prefix = "resume: ";
				break;

			default:
				prefix = "";
				break;
		}

		if ( node->type == NT_MAP && !G_MapExists( node->u.map.name ) )
		{
			colour = 1;
		}
		else if ( G_NodeIndexAfter( i - 1, mapRotationIndex ) == G_CurrentNodeIndex( mapRotationIndex ) )
		{
			colour = 3;

			if ( node->type == NT_MAP && Q_stricmp( node->u.map.name, currentMapName ) )
			{
				suffix = va( " (%s)", currentMapName );
			}
		}

		ADMBP(
		  va( " ^%i%3i %s%s%s\n",
		      colour,
		      i,
		      prefix,
		      node->type == NT_MAP ? node->u.map.name : node->u.label.name,
		      suffix ) );
	}

	if ( G_MapExists( g_nextMap.string ) )
	{
		ADMBP( va( "^7The next map has been set to %s\n", g_nextMap.string ) );
	}

	ADMBP_end();
}
示例#4
0
/*
===============
G_StepMapRotation

Run one node of a map rotation
===============
*/
qboolean G_StepMapRotation( int rotation, int nodeIndex, int depth )
{
	node_t      *node;
	condition_t *condition;
	int         returnRotation;
	qboolean    step = qtrue;

	node = G_NodeByIndex( nodeIndex, rotation );
	depth++;

	// guard against inifinite loop in conditional code
	if ( depth > 32 && node->type != NT_MAP )
	{
		if ( depth > 64 )
		{
			G_Printf( S_COLOR_RED "ERROR: infinite loop protection stopped at map rotation %s\n",
			          G_RotationNameByIndex( rotation ) );
			return qfalse;
		}

		G_Printf( S_COLOR_YELLOW "WARNING: possible infinite loop in map rotation %s\n",
		          G_RotationNameByIndex( rotation ) );
		return qtrue;
	}

	while ( step )
	{
		step = qfalse;

		switch ( node->type )
		{
			case NT_CONDITION:
				condition = &node->u.condition;

				if ( G_EvaluateMapCondition( &condition ) )
				{
					node = condition->target;
					step = qtrue;
					continue;
				}

				break;

			case NT_RETURN:
				returnRotation = G_PopRotationStack();

				if ( returnRotation >= 0 )
				{
					G_SetCurrentNodeByIndex(
					  G_NodeIndexAfter( nodeIndex, rotation ), rotation );

					if ( G_StartMapRotation( G_RotationNameByIndex( returnRotation ),
					                         qtrue, qfalse, qfalse, depth ) )
					{
						return qfalse;
					}
				}

				break;

			case NT_MAP:
				if ( G_MapExists( node->u.map.name ) )
				{
					G_SetCurrentNodeByIndex(
					  G_NodeIndexAfter( nodeIndex, rotation ), rotation );

					if ( !G_MapExists( g_nextMap.string ) )
					{
						G_IssueMapChange( nodeIndex, rotation );
					}

					return qfalse;
				}

				G_Printf( S_COLOR_YELLOW "WARNING: skipped missing map %s in rotation %s\n",
				          node->u.map.name, G_RotationNameByIndex( rotation ) );
				break;

			case NT_LABEL:
				break;

			case NT_GOTO:
			case NT_RESUME:
				G_SetCurrentNodeByIndex(
				  G_NodeIndexAfter( nodeIndex, rotation ), rotation );

				if ( G_GotoLabel( rotation, nodeIndex, node->u.label.name,
				                  ( node->type == NT_GOTO ), depth ) )
				{
					return qfalse;
				}

				G_Printf( S_COLOR_YELLOW "WARNING: label, map, or rotation %s not found in %s\n",
				          node->u.label.name, G_RotationNameByIndex( rotation ) );
				break;
		}
	}

	return qtrue;
}