Ejemplo n.º 1
0
/************************************************************************************************
 * CRMInstanceFile::Open
 *	Opens the given instance file and prepares it for use in instance creation
 *
 * inputs:
 *  instance: Name of instance to open.  Note that the root path will be automatically
 *			  added and shouldnt be included in the given name
 *
 * return:
 *	true: instance file successfully loaded
 *  false: instance file could not be loaded for some reason
 *
 ************************************************************************************************/
bool CRMInstanceFile::Open ( const char* instance )
{
    char		instanceDef[MAX_QPATH];
    CGPGroup	*basegroup;

    // Build the filename
    Com_sprintf(instanceDef, MAX_QPATH, "ext_data/rmg/%s.instance", instance );

#ifndef FINAL_BUILD
    // Debug message
    Com_Printf("CM_Terrain: Loading and parsing instanceDef %s.....\n", instance);
#endif

    // Parse the text file using the generic parser
    if(!Com_ParseTextFile(instanceDef, mParser ))
    {
        Com_sprintf(instanceDef, MAX_QPATH, "ext_data/arioche/%s.instance", instance );
        if(!Com_ParseTextFile(instanceDef, mParser ))
        {
            Com_Printf(va("CM_Terrain: Could not open instance file '%s'\n", instanceDef));
            return false;
        }
    }

    // The whole file....
    basegroup = mParser.GetBaseParseGroup();

    // The root { } struct
    mInstances = basegroup->GetSubGroups();

    // The "instances" { } structure
    mInstances = mInstances->GetSubGroups ( );

    return true;
}
Ejemplo n.º 2
0
bool CGPGroup::Parse(char **dataPtr, CTextPool **textPool)
{
	char		*token;
	char		lastToken[MAX_TOKEN_SIZE];
	CGPGroup	*newSubGroup;
	CGPValue	*newPair;

	while(1)
	{
		token = GetToken(dataPtr, true);

		if (!token[0])
		{	// end of data - error!
			if (mParent)
			{
				return false;
			}
			else
			{
				break;
			}
		}
		else if (strcmpi(token, "}") == 0)
		{	// ending brace for this group
			break;
		}

		strcpy(lastToken, token);

		// read ahead to see what we are doing
		token = GetToken(dataPtr, true, true);
		if (strcmpi(token, "{") == 0)
		{	// new sub group
			newSubGroup = AddGroup(lastToken, textPool);
			newSubGroup->SetWriteable(mWriteable);
			if (!newSubGroup->Parse(dataPtr, textPool))
			{
				return false;
			}
		}
		else if (strcmpi(token, "[") == 0)
		{	// new pair list
			newPair = AddPair(lastToken, 0, textPool);
			if (!newPair->Parse(dataPtr, textPool))
			{
				return false;
			}
		}
		else
		{	// new pair
			AddPair(lastToken, token, textPool);
		}
	}

	return true;
}
Ejemplo n.º 3
0
/************************************************************************************************
 * CRMRandomInstance::CRMRandomInstance
 *	constructs a random instance by choosing one of the sub instances and creating it
 *
 * inputs:
 *  instGroup:  parser group containing infromation about this instance
 *  instFile:   reference to an open instance file for creating sub instances
 *
 * return:
 *	none
 *
 ************************************************************************************************/
CRMRandomInstance::CRMRandomInstance ( CGPGroup *instGroup, CRMInstanceFile& instFile ) 
	: CRMInstance ( instGroup, instFile )
{
	CGPGroup* group;
	CGPGroup* groups[MAX_RANDOM_INSTANCES];
	int		  numGroups;

	// Build a list of the groups one can be chosen
	for ( numGroups = 0, group = instGroup->GetSubGroups ( ); 
		  group; 
		  group = group->GetNext ( ) )
	{
		// If this isnt an instance group then skip it
		if ( stricmp ( group->GetName ( ), "instance" ) )
		{
			continue;
		}

		int multiplier = atoi(group->FindPairValue ( "multiplier", "1" ));
		for ( ; multiplier > 0 && numGroups < MAX_RANDOM_INSTANCES; multiplier -- )
		{ 
			groups[numGroups++] = group;
		}
	}

	// No groups, no instance
	if ( !numGroups )
	{
		// Initialize this now
		mInstance = NULL;

		Com_Printf ( "WARNING: No sub instances specified for random instance '%s'\n", group->FindPairValue ( "name", "unknown" ) );
		return;
	}

	// Now choose a group to parse	
	instGroup = groups[TheRandomMissionManager->GetLandScape()->irand(0,numGroups-1)];

	// Create the child instance now.  If the instance create fails then the
	// IsValid routine will return false and this instance wont be added
	mInstance = instFile.CreateInstance ( instGroup->FindPairValue ( "name", "" ) );
	mInstance->SetFilter(mFilter);
	mInstance->SetTeamFilter(mTeamFilter);

	mAutomapSymbol = mInstance->GetAutomapSymbol();

	SetMessage(mInstance->GetMessage());
	SetDescription(mInstance->GetDescription());
	SetInfo(mInstance->GetInfo());
}
Ejemplo n.º 4
0
CGPGroup *CGPGroup::FindSubGroup(const char *name)
{
	CGPGroup	*group;

	group = mSubGroups;
	while(group)
	{
		if(!Q_stricmp(name, group->GetName()))
		{
			return(group);
		}
		group = (CGPGroup *)group->GetNext();
	}
	return(NULL);
}
Ejemplo n.º 5
0
int CGPGroup::GetNumSubGroups(void)
{
	int			count;
	CGPGroup	*group;

	count = 0;
	group = mSubGroups;
	while(group)
	{
		count++;
		group = (CGPGroup *)group->GetNext();
	}

	return(count);
}
Ejemplo n.º 6
0
void CGPGroup::Parse(char **dataPtr, CTextPool **textPool)
{
	char		*token;
	char		lastToken[MAX_TOKEN_SIZE];
	CGPGroup	*newSubGroup;
	CGPValue	*newPair;
	char		*name, *value;

	while(1)
	{
		token = GetToken(dataPtr, true);

		if (!token[0])
		{	// end of data - error!
			break;
		}
		else if (Q_strcmpi(token, "}") == 0)
		{	// ending brace for this group
			break;
		}

		strcpy(lastToken, token);

		// read ahead to see what we are doing
		token = GetToken(dataPtr, true, true);
		if (Q_strcmpi(token, "{") == 0)
		{	// new sub group
			name = (*textPool)->AllocText(lastToken, true, textPool);
			newSubGroup = AddGroup(name);
			newSubGroup->SetWriteable(mWriteable);
			newSubGroup->Parse(dataPtr, textPool);
		}
		else if (Q_strcmpi(token, "[") == 0)
		{	// new pair list
			name = (*textPool)->AllocText(lastToken, true, textPool);
			newPair = AddPair(name, 0);
			newPair->Parse(dataPtr, textPool);
		}
		else
		{	// new pair
			name = (*textPool)->AllocText(lastToken, true, textPool);
			value = (*textPool)->AllocText(token, true, textPool);
			AddPair(name, value);
		}
	}
}
Ejemplo n.º 7
0
bool CGPGroup::Write(CTextPool **textPool, int depth)
{
	int				i;
	CGPValue		*mPair = mPairs;
	CGPGroup		*mSubGroup = mSubGroups;

	if (depth >= 0)
	{
		for(i=0;i<depth;i++)
		{
			(*textPool)->AllocText("\t", false, textPool);
		}
		WriteText(textPool, mName);
		(*textPool)->AllocText("\r\n", false, textPool);
		
		for(i=0;i<depth;i++)
		{
			(*textPool)->AllocText("\t", false, textPool);
		}
		(*textPool)->AllocText("{\r\n", false, textPool);
	}

	while(mPair)
	{
		mPair->Write(textPool, depth+1);
		mPair = (CGPValue *)mPair->GetNext();
	}

	while(mSubGroup)
	{
		mSubGroup->Write(textPool, depth+1);
		mSubGroup = (CGPGroup *)mSubGroup->GetNext();
	}

	if (depth >= 0)
	{
		for(i=0;i<depth;i++)
		{
			(*textPool)->AllocText("\t", false, textPool);
		}
		(*textPool)->AllocText("}\r\n", false, textPool);
	}

	return true;
}
Ejemplo n.º 8
0
bool CPrimitiveTemplate::ParseGroup( const CGPGroup& grp, const StringViewIMap< ParseMethod >& parseMethods, gsl::czstring name )
{
	for( auto& cur : grp.GetProperties() )
	{
		auto pos = parseMethods.find( cur.GetName() );
		if( pos == parseMethods.end() )
		{
			theFxHelper.Print( "Unknown key parsing %s group!", name );
		}
		else
		{
			ParseMethod method = pos->second;
			( this->*method )( cur.GetTopValue() );
		}
	}
	return true;
}
Ejemplo n.º 9
0
/************************************************************************************************
 * CRMInstanceFile::CreateInstance
 *	Creates an instance (to be freed by caller) using the given instance name.
 *
 * inputs:
 *  name: Name of the instance to read from the instance file
 *
 * return:
 *	NULL: instance could not be read from the instance file
 *  NON-NULL: instance created and returned for further use
 *
 ************************************************************************************************/
CRMInstance* CRMInstanceFile::CreateInstance ( const char* name )
{
    static int instanceID = 0;

    CGPGroup*		group;
    CRMInstance*	instance;

    // Make sure we were loaded
    assert ( mInstances );

    // Search through the instances for the one with the given name
    for ( group = mInstances; group; group = group->GetNext ( ) )
    {
        // Skip it if the name doesnt match
        if ( stricmp ( name, group->FindPairValue ( "name", "" ) ) )
        {
            continue;
        }

        // Handle the various forms of instance types
        if ( !stricmp ( group->GetName ( ), "bsp" ) )
        {
            instance = new CRMBSPInstance ( group, *this );
        }
        else if ( !stricmp ( group->GetName ( ), "npc" ) )
        {
//			instance = new CRMNPCInstance ( group, *this );
            continue;
        }
        else if ( !stricmp ( group->GetName ( ), "group" ) )
        {
            instance = new CRMGroupInstance ( group, *this );
        }
        else if ( !stricmp ( group->GetName ( ), "random" ) )
        {
            instance = new CRMRandomInstance ( group, *this );
        }
        else if ( !stricmp ( group->GetName ( ), "void" ) )
        {
            instance = new CRMVoidInstance ( group, *this );
        }
        else
        {
            continue;
        }

        // If the instance isnt valid after being created then delete it
        if ( !instance->IsValid ( ) )
        {
            delete instance;
            return NULL;
        }

        // The instance was successfully created so return it
        return instance;
    }

#ifndef FINAL_BUILD
    // The instance wasnt found in the file so report it
    Com_Printf(va("WARNING:  Instance '%s' was not found in the active instance file\n", name ));
#endif

    return NULL;
}
Ejemplo n.º 10
0
// Parse a primitive, apply defaults first, grab any base level
//	key pairs, then process any sub groups we may contain.
//------------------------------------------------------
bool CPrimitiveTemplate::ParsePrimitive( CGPGroup *grp )
{
	CGPGroup	*subGrp;
	CGPValue	*pairs;
	const char	*key; 
	const char	*val;

	// Lets work with the pairs first
	pairs = grp->GetPairs();

	while( pairs )
	{
		// the fields
		key = pairs->GetName();
		val = pairs->GetTopValue();

		// Huge stricmp lists suxor
		if ( !stricmp( key, "count" ))
		{
			ParseCount( val );
		}
		else if ( !stricmp( key, "shaders" ) || !stricmp( key, "shader" ))
		{
			ParseShaders( pairs );
		}
		else if ( !stricmp( key, "models" ) || !stricmp( key, "model" ))
		{
			ParseModels( pairs );
		}
		else if ( !stricmp( key, "sounds" ) || !stricmp( key, "sound" ))
		{
			ParseSounds( pairs );
		}
		else if ( !stricmp( key, "impactfx" ))
		{
			ParseImpactFxStrings( pairs );
		}
		else if ( !stricmp( key, "deathfx" ))
		{
			ParseDeathFxStrings( pairs );
		}
		else if ( !stricmp( key, "emitfx" ))
		{
			ParseEmitterFxStrings( pairs );
		}
		else if ( !stricmp( key, "playfx" ))
		{
			ParsePlayFxStrings( pairs );
		}
		else if ( !stricmp( key, "life" ))
		{
			ParseLife( val );
		}
		else if ( !stricmp( key, "cullrange" ))
		{
			mCullRange = atoi( val );
			mCullRange *= mCullRange; // Square
		}
		else if ( !stricmp( key, "delay" ))
		{
			ParseDelay( val );
		}
		else if ( !stricmp( key, "bounce" ) || !stricmp( key, "intensity" )) // me==bad for reusing this...but it shouldn't hurt anything)
		{
			ParseElasticity( val );
		}
		else if ( !stricmp( key, "min" ))
		{
			ParseMin( val );
		}
		else if ( !stricmp( key, "max" ))
		{
			ParseMax( val );
		}
		else if ( !stricmp( key, "angle" ) || !stricmp( key, "angles" ))
		{
			ParseAngle( val );
		}
		else if ( !stricmp( key, "angleDelta" ))
		{
			ParseAngleDelta( val );
		}
		else if ( !stricmp( key, "velocity" ) || !stricmp( key, "vel" ))
		{
			ParseVelocity( val );
		}
		else if ( !stricmp( key, "acceleration" ) || !stricmp( key, "accel" ))
		{
			ParseAcceleration( val );
		}
		else if ( !stricmp( key, "gravity" ))
		{
			ParseGravity( val );
		}
		else if ( !stricmp( key, "density" ))
		{
			ParseDensity( val );
		}
		else if ( !stricmp( key, "variance" ))
		{
			ParseVariance( val );
		}
		else if ( !stricmp( key, "origin" ))
		{
			ParseOrigin1( val );
		}
		else if ( !stricmp( key, "origin2" ))
		{
			ParseOrigin2( val );
		}
		else if ( !stricmp( key, "radius" )) // part of ellipse/cylinder calcs.
		{
			ParseRadius( val );
		}
		else if ( !stricmp( key, "height" )) // part of ellipse/cylinder calcs.
		{
			ParseHeight( val );
		}
		else if ( !stricmp( key, "rotation" ))
		{
			ParseRotation( val );
		}
		else if ( !Q_stricmp( key, "rotationDelta" ))
		{
			ParseRotationDelta( val );
		}
		else if ( !stricmp( key, "flags" ) || !stricmp( key, "flag" ))
		{ // these need to get passed on to the primitive
			ParseFlags( val );
		}
		else if ( !stricmp( key, "spawnFlags" ) || !stricmp( key, "spawnFlag" ))
		{ // these are used to spawn things in cool ways, but don't ever get passed on to prims.
			ParseSpawnFlags( val );
		}
		else if ( !stricmp( key, "name" ))
		{
			if ( val )
			{
				// just stash the descriptive name of the primitive
				strcpy( mName, val );
			}
		}
		else
		{
			theFxHelper.Print( "Unknown key parsing an effect primitive: %s\n", key );
		}

		pairs = (CGPValue *)pairs->GetNext();
	}

	subGrp = grp->GetSubGroups();

	// Lets chomp on the groups now
	while ( subGrp )
	{
		key = subGrp->GetName();

		if ( !stricmp( key, "rgb" ))
		{
			ParseRGB( subGrp );
		}
		else if ( !stricmp( key, "alpha" ))
		{
			ParseAlpha( subGrp );
		}
		else if ( !stricmp( key, "size" ) || !stricmp( key, "width" ))
		{
			ParseSize( subGrp );
		}
		else if ( !stricmp( key, "size2" ) || !stricmp( key, "width2" ))
		{
			ParseSize2( subGrp );
		}
		else if ( !stricmp( key, "length" ) || !stricmp( key, "height" ))
		{
			ParseLength( subGrp );
		}
		else
		{
			theFxHelper.Print( "Unknown group key parsing a particle: %s\n", key );
		}

		subGrp = (CGPGroup *)subGrp->GetNext();
	}

	return true;
}
Ejemplo n.º 11
0
static sboolean Music_ParseLeveldata(const char *psLevelName)
{
	sboolean bReturn = qfalse;

	if (MusicData == NULL)
	{
		MusicData = new MusicData_t;
	}
	
		// already got this data?
	//
	if (MusicData->size() && !Q_stricmp(psLevelName,gsLevelNameForCompare.c_str()))
	{
		return qtrue;
	}
	
	MusicData->clear();	

	char sLevelName[MAX_QPATH];
	Q_strncpyz(sLevelName,psLevelName,sizeof(sLevelName));
	
	gsLevelNameForLoad		= sLevelName;	// harmless to init here even if we fail to parse dms.dat file	
	gsLevelNameForCompare	= sLevelName;	// harmless to init here even if we fail to parse dms.dat file	
	gsLevelNameForBossLoad	= sLevelName;	// harmless to init here even if we fail to parse dms.dat file	

	char *pText = NULL;
	/*int iTotalBytesLoaded = */FS_ReadFile(sFILENAME_DMS, (void **)&pText );			
	if (pText) 
	{
		char *psStrippedText = StripTrailingWhiteSpaceOnEveryLine(pText);		
		CGenericParser2 Parser;
		char *psDataPtr = psStrippedText;	// because ptr gets advanced, so we supply a clone that GP can alter
		if (Parser.Parse(&psDataPtr, true))
		{
			CGPGroup *pFileGroup = Parser.GetBaseParseGroup();
			if (pFileGroup)
			{
				CGPGroup *pgMusicFiles = pFileGroup->FindSubGroup(sKEY_MUSICFILES);
				if (pgMusicFiles)
				{
					CGPGroup *pgLevelMusic = pFileGroup->FindSubGroup(sKEY_LEVELMUSIC);

					if (pgLevelMusic)
					{
						CGPGroup *pgThisLevelMusic = NULL;
						//
						// check for new USE keyword...
						//
						int iSanityLimit = 0;
						sstring_t sSearchName(sLevelName);

						while (sSearchName.c_str()[0] && iSanityLimit < 10)
						{
							gsLevelNameForLoad		= sSearchName;
							gsLevelNameForBossLoad	= sSearchName;
							pgThisLevelMusic = pgLevelMusic->FindSubGroup(sSearchName.c_str());

							if (pgThisLevelMusic)
							{
								CGPValue *pValue = pgThisLevelMusic->FindPair(sKEY_USES);
								if (pValue)
								{
									// re-search using the USE param...
									//									
									sSearchName = pValue->GetTopValue();
									iSanityLimit++;
//									Com_DPrintf("Using \"%s\"\n",sSearchName.c_str());
								}
								else
								{
									// no new USE keyword found...
									//
									sSearchName = "";
								}
							}
							else
							{
								// level entry not found...
								//
								break;
							}
						}

						// now go ahead and use the final music set we've decided on...
						//
						if (pgThisLevelMusic && iSanityLimit < 10)
						{
							// these are optional fields, so see which ones we find...
							//
							LPCSTR psName_Explore = NULL;
							LPCSTR psName_Action  = NULL;
							LPCSTR psName_Boss	  = NULL;
							LPCSTR psName_Death	  = NULL;
							//
							LPCSTR psName_UseBoss = NULL;

							for (CGPValue *pValue = pgThisLevelMusic->GetPairs(); pValue; pValue = pValue->GetNext())
							{
								LPCSTR psKey	= pValue->GetName();
								LPCSTR psValue	= pValue->GetTopValue();								

								if (Q_stricmp(psValue,sKEY_PLACEHOLDER))	// ignore "placeholder" items
								{
									if (!Q_stricmp(psKey,sKEY_EXPLORE))
									{
										psName_Explore = psValue;
									}
									else
									if (!Q_stricmp(psKey,sKEY_ACTION))
									{
										psName_Action  = psValue;
									}
									else
									if (!Q_stricmp(psKey,sKEY_USEBOSS))
									{
										psName_UseBoss = psValue;
									}
									else
									if (!Q_stricmp(psKey,sKEY_BOSS))
									{
										psName_Boss = psValue;
									}
									else
									if (!Q_stricmp(psKey,sKEY_DEATH))
									{
										psName_Death = psValue;
									}
								}
							}
									
							bReturn = qtrue;	// defualt to ON now, so I can turn it off if "useboss" fails

							if (psName_UseBoss)
							{
								CGPGroup *pgLevelMusicOfBoss = pgLevelMusic->FindSubGroup(psName_UseBoss);
								if (pgLevelMusicOfBoss)
								{
									CGPValue *pValueBoss = pgLevelMusicOfBoss->FindPair(sKEY_BOSS);
									if (pValueBoss)
									{	
										psName_Boss = pValueBoss->GetTopValue();
										gsLevelNameForBossLoad = psName_UseBoss;
									}
									else
									{
										MUSIC_PARSE_ERROR(va("'useboss' \"%s\" has no \"boss\" entry!\n",psName_UseBoss));
										bReturn = qfalse;
									}
								}
								else
								{
									MUSIC_PARSE_ERROR(va("Unable to find 'useboss' entry \"%s\"\n",psName_UseBoss));									
									bReturn = qfalse;
								}
							}


							// done this way in case I want to conditionally pass any bools depending on music type...
							//
							if (bReturn && psName_Explore)
							{
								bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Explore,	sKEY_EXPLORE, eBGRNDTRACK_EXPLORE);
							}
							if (bReturn && psName_Action)
							{
								bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Action,	sKEY_ACTION,  eBGRNDTRACK_ACTION);
							}
							if (bReturn && psName_Boss)
							{
								bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Boss,	sKEY_BOSS,    eBGRNDTRACK_BOSS);
							}
							if (bReturn /*&& psName_Death*/)	// LAST MINUTE HACK!!, always force in some death music!!!!
							{
								//bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Death,	sKEY_DEATH,   eBGRNDTRACK_DEATH);

								MusicFile_t m;
											m.sFileNameBase = "death_music";
								(*MusicData)[ sKEY_DEATH ] = m;
							}
						}
						else
						{
							MUSIC_PARSE_WARNING(va("Unable to find entry for \"%s\" in \"%s\"\n",sLevelName,sFILENAME_DMS));
						}
					}
					else
					{
						MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\"\n",sKEY_LEVELMUSIC));
					}
				}
				else
				{
					MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\"\n",sKEY_MUSICFILES));
				}
			}
			else
			{
				MUSIC_PARSE_ERROR( "Error calling GP2.GetBaseParseGroup()\n" );
			}
		}
		else
		{
			MUSIC_PARSE_ERROR( "Error using GP to parse file\n" );
		}

		Z_Free(psStrippedText);
		FS_FreeFile( pText );
	}
	else
	{
		MUSIC_PARSE_ERROR( "Unable to even read main file\n" );	// file name specified in error message
	}

	if (bReturn)
	{
		// sort exit points, and do some error checking...
		//
		for (MusicData_t::iterator itMusicData = MusicData->begin(); itMusicData != MusicData->end(); ++itMusicData)
		{
			LPCSTR psMusicStateType	= (*itMusicData).first.c_str();
			MusicFile_t &MusicFile	= (*itMusicData).second;

			// kludge up an enum, only interested in boss or not at the moment, so...
			//
			MusicState_e eMusicState = !stricmp(psMusicStateType,"boss") ? eBGRNDTRACK_BOSS : !stricmp(psMusicStateType,"death") ? eBGRNDTRACK_DEATH : eBGRNDTRACK_EXPLORE;

			if (!MusicFile.MusicExitTimes.empty())
			{
				sort(MusicFile.MusicExitTimes.begin(),MusicFile.MusicExitTimes.end());
			}

			// check music exists...
			//
			LPCSTR psMusicFileName = Music_BuildFileName( MusicFile.sFileNameBase.c_str(), eMusicState );
			if (!S_FileExists( psMusicFileName ))
			{
				MUSIC_PARSE_ERROR(va("Music file \"%s\" not found!\n",psMusicFileName));
				return qfalse;		// have to return, because music data destroyed now
			}

			// check all transition music pieces exist, and that entry points into new pieces after transitions also exist...
			//
			for (int iExitPoint=0; iExitPoint < MusicFile.MusicExitPoints.size(); iExitPoint++)
			{
				MusicExitPoint_t &MusicExitPoint = MusicFile.MusicExitPoints[ iExitPoint ];

				LPCSTR psTransitionFileName = Music_BuildFileName( MusicExitPoint.sNextFile.c_str(), eMusicState );
				if (!S_FileExists( psTransitionFileName ))
				{
					MUSIC_PARSE_ERROR(va("Transition file \"%s\" (entry \"%s\" ) not found!\n",psTransitionFileName, MusicExitPoint.sNextFile.c_str()));
					return qfalse;		// have to return, because music data destroyed now
				}

				LPCSTR psNextMark = MusicExitPoint.sNextMark.c_str();
				if (strlen(psNextMark))	// always NZ ptr
				{
					// then this must be "action" music under current rules...
					//					
					assert( !strcmp(psMusicStateType, Music_BaseStateToString(eBGRNDTRACK_ACTION) ? Music_BaseStateToString(eBGRNDTRACK_ACTION):"") );
					//
					// does this marker exist in the explore piece?
					//					
					MusicData_t::iterator itExploreMusicData = MusicData->find( Music_BaseStateToString(eBGRNDTRACK_EXPLORE) );
					if (itExploreMusicData != MusicData->end())
					{
						MusicFile_t &MusicFile_Explore = (*itExploreMusicData).second;

						if (!MusicFile_Explore.MusicEntryTimes.count(psNextMark))
						{
							MUSIC_PARSE_ERROR( va("Unable to find entry point \"%s\" in description for \"%s\"\n",psNextMark,MusicFile_Explore.sFileNameBase.c_str()) );
							return qfalse;		// have to return, because music data destroyed now
						}
					}
					else
					{
						MUSIC_PARSE_ERROR( va("Unable to find %s piece to match \"%s\"\n", Music_BaseStateToString(eBGRNDTRACK_EXPLORE), MusicFile.sFileNameBase.c_str() ) );
						return qfalse;		// have to return, because music data destroyed now
					}
				}
			}
		}
	}
	
#ifdef _DEBUG
/*
	// dump the whole thing out to prove it was read in ok...
	//
	if (bReturn)
	{
		for (MusicData_t::iterator itMusicData = MusicData->begin(); itMusicData != MusicData->end(); ++itMusicData)
		{
			LPCSTR psMusicState		= (*itMusicData).first.c_str();
			MusicFile_t &MusicFile	= (*itMusicData).second;

			OutputDebugString(va("Music State:  \"%s\",  File: \"%s\"\n",psMusicState, MusicFile.sFileNameBase.c_str()));

			// entry times...
			//
			for (MusicEntryTimes_t::iterator itEntryTimes = MusicFile.MusicEntryTimes.begin(); itEntryTimes != MusicFile.MusicEntryTimes.end(); ++itEntryTimes)
			{
				LPCSTR	psMarkerName	= (*itEntryTimes).first.c_str();
				float	fEntryTime		= (*itEntryTimes).second;

				OutputDebugString(va("Entry time for \"%s\": %f\n", psMarkerName, fEntryTime));
			}

			// exit points...
			//
			for (int i=0; i<MusicFile.MusicExitPoints.size(); i++)
			{
				MusicExitPoint_t &MusicExitPoint = MusicFile.MusicExitPoints[i];

				OutputDebugString(va("Exit point %d:	sNextFile: \"%s\", sNextMark: \"%s\"\n",i,MusicExitPoint.sNextFile.c_str(),MusicExitPoint.sNextMark.c_str()));
			}

			// exit times...
			//
			for (i=0; i<MusicFile.MusicExitTimes.size(); i++)
			{
				MusicExitTime_t &MusicExitTime = MusicFile.MusicExitTimes[i];
				
				OutputDebugString(va("Exit time %d:		fTime: %f, iExitPoint: %d\n",i,MusicExitTime.fTime,MusicExitTime.iExitPoint));
			}
		}
	}
*/
#endif

	return bReturn;
}
Ejemplo n.º 12
0
static bool Music_ParseMusic( gsl::czstring filename, const CGenericParser2& Parser, MusicData_t* MusicData, const CGPGroup& pgMusicFiles, const gsl::cstring_view& psMusicName, const gsl::cstring_view& psMusicNameKey, MusicState_e eMusicState )
{
	bool bReturn = false;
	MusicFile_t MusicFile;

	const CGPGroup* pgMusicFile = pgMusicFiles.FindSubGroup( psMusicName );
	if( pgMusicFile )
	{
		// read subgroups...
		//
		bool bEntryFound = false;
		bool bExitFound = false;
		//
		// (read entry points first, so I can check exit points aren't too close in time)
		//
		const CGPGroup* pEntryGroup = pgMusicFile->FindSubGroup( sKEY_ENTRY );
		if( pEntryGroup )
		{
			// read entry points...
			//
			for( auto& prop : pEntryGroup->GetProperties() )
			{
				//if (!strncmp(psKey,sKEY_MARKER,strlen(sKEY_MARKER)))	// for now, assume anything is a marker
				MusicFile.MusicEntryTimes[ StringViewToSString( prop.GetName() ) ] = Q::svtoi( prop.GetTopValue() );
				bEntryFound = true;
			}
		}

		for( auto& group : pgMusicFile->GetSubGroups() )
		{
			auto& groupName = group.GetName();

			if( groupName == sKEY_ENTRY )
			{
				// skip entry points, I've already read them in above
				//
			}
			else if( groupName == sKEY_EXIT )
			{
				int iThisExitPointIndex = MusicFile.MusicExitPoints.size();	// must eval this first, so unaffected by push_back etc
				//
				// read this set of exit points...
				//
				MusicExitPoint_t MusicExitPoint;
				for( auto& prop : group.GetProperties() )
				{
					auto& key = prop.GetName();
					auto& value = prop.GetTopValue();

					if( key == sKEY_NEXTFILE )
					{
						MusicExitPoint.sNextFile = StringViewToSString( value );
						bExitFound = true;	// harmless to keep setting
					}
					else if( key == sKEY_NEXTMARK )
					{
						MusicExitPoint.sNextMark = StringViewToSString( value );
					}
					else if( key == sKEY_TIME )
					{
						MusicExitTime_t MusicExitTime;
						MusicExitTime.fTime = Q::svtof( value );
						MusicExitTime.iExitPoint = iThisExitPointIndex;

						// new check, don't keep this this exit point if it's within 1.5 seconds either way of an entry point...
						//
						bool bTooCloseToEntryPoint = false;
						for( auto& item : MusicFile.MusicEntryTimes )
						{
							float fThisEntryTime = item.second;

							if( Q_fabs( fThisEntryTime - MusicExitTime.fTime ) < 1.5f )
							{
								//								bTooCloseToEntryPoint = true;	// not sure about this, ignore for now
								break;
							}
						}
						if( !bTooCloseToEntryPoint )
						{
							MusicFile.MusicExitTimes.push_back( MusicExitTime );
						}
					}
				}

				MusicFile.MusicExitPoints.push_back( MusicExitPoint );
				int iNumExitPoints = MusicFile.MusicExitPoints.size();

				// error checking...
				//
				switch( eMusicState )
				{
				case eBGRNDTRACK_EXPLORE:
					if( iNumExitPoints > iMAX_EXPLORE_TRANSITIONS )
					{
						Music_Parse_Error( filename, build_string( "\"", psMusicName, "\" has > ", iMAX_EXPLORE_TRANSITIONS, " ", psMusicNameKey, " transitions defined!\n" ) );
						return false;
					}
					break;

				case eBGRNDTRACK_ACTION:
					if( iNumExitPoints > iMAX_ACTION_TRANSITIONS )
					{
						Music_Parse_Error( filename, build_string( "\"", psMusicName, "\" has > ", iMAX_ACTION_TRANSITIONS, " ", psMusicNameKey, " transitions defined!\n" ) );
						return false;
					}
					break;

				case eBGRNDTRACK_BOSS:
				case eBGRNDTRACK_DEATH:

					Music_Parse_Error( filename, build_string( "\"", psMusicName, "\" has ", psMusicNameKey, " transitions defined, this is not allowed!\n" ) );
					return false;
				default:
					break;
				}
			}
		}

		// for now, assume everything was ok unless some obvious things are missing...
		//
		bReturn = true;

		// boss & death pieces can omit entry/exit stuff
		if( eMusicState != eBGRNDTRACK_BOSS && eMusicState != eBGRNDTRACK_DEATH )
		{
			if( !bEntryFound )
			{
				Music_Parse_Error( filename, build_string( "Unable to find subgroup \"", sKEY_ENTRY, "\" in group \"", psMusicName, "\"\n" ) );
				bReturn = false;
			}
			if( !bExitFound )
			{
				Music_Parse_Error( filename, build_string( "Unable to find subgroup \"", sKEY_EXIT, "\" in group \"", psMusicName, "\"\n" ) );
				bReturn = false;
			}
		}
	}
	else
	{
		Music_Parse_Error( filename, build_string( "Unable to find musicfiles entry \"", psMusicName, "\"\n" ) );
	}

	if( bReturn )
	{
		MusicFile.sFileNameBase = StringViewToSString( psMusicName );
		( *MusicData )[ StringViewToSString( psMusicNameKey ) ] = MusicFile;
	}

	return bReturn;
}
Ejemplo n.º 13
0
// returns true if at least one set of skin data was read, else false...
//
static bool Skins_Read(LPCSTR psModelFilename)
{
	LPCSTR psError = NULL;

	CWaitCursor;

	LPCSTR psSkinsPath = Skins_ModelNameToSkinPath(psModelFilename);	// eg "models/characters/skins"

	if (psSkinsPath)
	{
		string strThisModelBaseName(String_ToLower(Filename_WithoutExt(Filename_WithoutPath(psModelFilename))));

		char **ppsSkinFiles;
		int iSkinFiles;

		// scan for skin files...
		//
		ppsSkinFiles =	//ri.FS_ListFiles( "shaders", ".shader", &iSkinFiles );
						Sys_ListFiles(	va("%s%s",gamedir,psSkinsPath),// const char *directory, 
										".g2skin",	// const char *extension, 
										NULL,		// char *filter, 
										&iSkinFiles,// int *numfiles, 
										qfalse		// qboolean wantsubs 
										);

		if ( !ppsSkinFiles || !iSkinFiles )
		{
			CurrentSkins.clear();	
			CurrentSkinsSurfacePrefs.clear();
			return false;
		}

		if ( iSkinFiles > MAX_SKIN_FILES ) 
		{
			WarningBox(va("%d skin files found, capping to %d\n\n(tell me if this ever happens -Ste)", iSkinFiles, MAX_SKIN_FILES ));

			iSkinFiles = MAX_SKIN_FILES;
		}

		// load and parse skin files...
		//					
		// for now, I just scan each file and if it's out of date then I invalidate it's model-prefs info...
		//
		extern bool GetFileTime(LPCSTR psFileName, FILETIME &ft);
		for (int i=0; i<iSkinFiles; i++)
		{
			bool bReParseThisFile = false;

			char sFileName[MAX_QPATH];
			LPCSTR psFileName = ppsSkinFiles[i];
			Com_sprintf( sFileName, sizeof( sFileName ), "%s/%s", psSkinsPath, psFileName );
			psFileName = &sFileName[0];
											  
			// have a go at getting this time/date stamp if not already present...
			//
			if (!SkinFileTimeDates[psFileName].bValid)
			{
				FILETIME ft;
				if (GetFileTime(psFileName, ft))
				{
					SkinFileTimeDates[psFileName].ft = ft;
					SkinFileTimeDates[psFileName].bValid = true;
				}
			}

			// now see if there's a valid time-stamp, and use it if so, else give up and re-scan all files...
			//
			if (SkinFileTimeDates[psFileName].bValid)
			{
				FILETIME ft;
				if (GetFileTime(psFileName, ft))
				{
					LONG l = CompareFileTime( &SkinFileTimeDates[psFileName].ft, &ft);

					bReParseThisFile = (l<0);
				}
				else
				{
					bReParseThisFile = true;
				}
			}
			else
			{
				bReParseThisFile = true;
			}	
			
			if (bReParseThisFile)
			{
				G2SkinModelPrefs[sFileName].clear();
			}
		}		
		
		if (1)//bReParseSkinFiles || !CurrentSkins.size())
		{
			CurrentSkins.clear();	
			CurrentSkinsSurfacePrefs.clear();

			char *buffers[MAX_SKIN_FILES]={0};
//			long iTotalBytesLoaded = 0;
			for ( int i=0; i<iSkinFiles && !psError; i++ )
			{
				char sFileName[MAX_QPATH];

				string strThisSkinFile(ppsSkinFiles[i]);

				Com_sprintf( sFileName, sizeof( sFileName ), "%s/%s", psSkinsPath, strThisSkinFile.c_str() );
				StatusMessage( va("Scanning skin %d/%d: \"%s\"...",i+1,iSkinFiles,sFileName));

				//ri.Printf( PRINT_ALL, "...loading '%s'\n", sFileName );

				bool _bDiskLoadOccured = false;	// debug use only, but wtf?

#define LOAD_SKIN_FILE									\
/*iTotalBytesLoaded += */ ri.FS_ReadFile( sFileName, (void **)&buffers[i] );	\
if ( !buffers[i] )										\
{														\
	CurrentSkins.clear();								\
	CurrentSkinsSurfacePrefs.clear();					\
														\
	ri.Error( ERR_DROP, "Couldn't load %s", sFileName );\
}														\
_bDiskLoadOccured = true;


				// see if we should pay attention to the contents of this file...
				//
				CGPGroup	*pFileGroup			= NULL;
				CGPGroup *pParseGroup_Prefs	= NULL;
				CGenericParser2 SkinParser;
				//
				bool bParseThisFile = false;
				//
				// if we have any information about this skin file as regards what models it refers to, use the info...
				//
				if (G2SkinModelPrefs[sFileName].size())
				{
					map<string, int>::iterator it = G2SkinModelPrefs[sFileName].find( strThisModelBaseName );
					if (it != G2SkinModelPrefs[sFileName].end())
					{
						// this skin file contains this entry, so just check that we can setup the parse groups ok...
						//
						LOAD_SKIN_FILE;

						char *psDataPtr = buffers[i];
						if (SkinParser.Parse(&psDataPtr, true))
						{
							pFileGroup = SkinParser.GetBaseParseGroup();
							if (pFileGroup)
							{
								pParseGroup_Prefs = pFileGroup->FindSubGroup(sSKINKEYWORD_PREFS);//, true);
								if (pParseGroup_Prefs)
								{
									bParseThisFile = true;
								}
							}
						}
						else
						{
							ErrorBox(va("{} - Brace mismatch error in file \"%s\"!",sFileName));
						}
					}
				}
				else
				{
					// no size info for this file, so check it manually...
					//
					LOAD_SKIN_FILE;

					if (Skins_ParseThisFile(SkinParser, buffers[i], strThisModelBaseName, pFileGroup, pParseGroup_Prefs, 
											sFileName, G2SkinModelPrefs)
						)
					{
						bParseThisFile = true;
					}
				}

				if (bParseThisFile)
				{
					psError = Skins_Parse( strThisSkinFile, pFileGroup, pParseGroup_Prefs);
					if (psError)
					{
						ErrorBox(va("Skins_Read(): Error reading file \"%s\"!\n\n( Skins will be ignored for this model )\n\nError was:\n\n",sFileName,psError));
					}
				}
				else
				{
					//OutputDebugString(va("Skipping parse of file \"%s\" %s\n",sFileName, _bDiskLoadOccured?"":"( and no load! )"));
				}
			}
			//
			// free loaded skin files...
			//
			for ( i=0; i<iSkinFiles; i++ )
			{
				if (buffers[i])
				{
					ri.FS_FreeFile( buffers[i] );
				}
			}
		}

		StatusMessage(NULL);
		Sys_FreeFileList( ppsSkinFiles );
	}
	else
	{
		CurrentSkins.clear();	
		CurrentSkinsSurfacePrefs.clear();
	}

	if (psError)
	{
		return false;
	}

	return !!(CurrentSkins.size());
}
Ejemplo n.º 14
0
static LPCSTR Skins_Parse(string strThisSkinFileName, CGPGroup *pFileGroup, CGPGroup *pParseGroup_Prefs)
{
	LPCSTR psError = NULL;

	// read any optional surface on/off blocks...
	//
	for (int iSurfaceOnOffType = 0; iSurfaceOnOffType<3; iSurfaceOnOffType++)
	{
		CGPGroup *pSurfaceParseGroup = NULL;
		switch (iSurfaceOnOffType)
		{
			case 0: pSurfaceParseGroup = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_SURFACES_ON);				break;
			case 1: pSurfaceParseGroup = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_SURFACES_OFF);			break;
			case 2: pSurfaceParseGroup = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_SURFACES_OFFNOCHILDREN);	break;
			default: assert(0);	break;
		}

		if (pSurfaceParseGroup)
		{
			CGPValue *pValue = pSurfaceParseGroup->GetPairs();
			while (pValue)
			{			
//				string str1 = (*it).first;	// junk, eg "name1"
				string str2 = pValue->GetTopValue();
				
				switch (iSurfaceOnOffType)
				{
					case 0: CurrentSkinsSurfacePrefs[strThisSkinFileName].vSurfacesOn.push_back(str2);	break;
					case 1: CurrentSkinsSurfacePrefs[strThisSkinFileName].vSurfacesOff.push_back(str2);	break;
					case 2: CurrentSkinsSurfacePrefs[strThisSkinFileName].vSurfacesOffNoChildren.push_back(str2);	break;
					default: assert(0);	break;
				}

				pValue = pValue->GetNext();
			}
		}
	}

	// find all the materials and add them to the skin set...
	//
	int iMaterialDeclarationIndex = 0;
	for (CGPGroup *pMaterialGroup = pFileGroup->GetSubGroups(); pMaterialGroup; pMaterialGroup = pMaterialGroup->GetNext(), iMaterialDeclarationIndex++)
	{
		string strKeyWord = pMaterialGroup->GetName();

		if (strKeyWord == sSKINKEYWORD_MATERIAL)
		{
			string strMaterialName(pMaterialGroup->FindPairValue(sSKINKEYWORD_NAME,""));

			if (strMaterialName == "")
			{
				psError = va("%s[%d] had no \"%s\" field!\n",sSKINKEYWORD_MATERIAL, iMaterialDeclarationIndex, sSKINKEYWORD_NAME);
				return psError;
			}

			// now iterate through the ethnic group variants of this material...
			//
			int iEthnicGroupIndex = 0;
			for (CGPGroup *pEthnicGroup = pMaterialGroup->GetSubGroups(); pEthnicGroup; pEthnicGroup = pEthnicGroup->GetNext(), iEthnicGroupIndex++)
			{
				strKeyWord = pEthnicGroup->GetName();

				if (strKeyWord == sSKINKEYWORD_GROUP)
				{
					string strEthnicGroupName(pEthnicGroup->FindPairValue(sSKINKEYWORD_NAME,""));

					if (strEthnicGroupName == "")
					{
						psError = va("%s[%d] %s[%d] had no \"%s\" field!\n",sSKINKEYWORD_MATERIAL, iMaterialDeclarationIndex, sSKINKEYWORD_GROUP, iEthnicGroupIndex, sSKINKEYWORD_NAME);
						return psError;
					}

					// now iterate through the shader variants for this ethnic version of this material...  (is anyone reading this...?)
					//
					int iAlternateShaderIndex = 0;
					for (CGPValue *pValue = pEthnicGroup->GetPairs(); pValue; pValue = pValue->GetNext())
					{
						string strField(pValue->GetName());

						if (strField != sSKINKEYWORD_NAME)
						{
							// ... then it should be a shader...
							//
							string strShader(pValue->GetTopValue());

							CurrentSkins[strThisSkinFileName][strEthnicGroupName][strMaterialName].push_back(strShader);
						}
					}
				}
			}
		}
	}

	return psError;
}
Ejemplo n.º 15
0
// Parse a primitive, apply defaults first, grab any base level
//	key pairs, then process any sub groups we may contain.
//------------------------------------------------------
bool CPrimitiveTemplate::ParsePrimitive( const CGPGroup& grp )
{
	// Property
	for( auto& prop : grp.GetProperties() )
	{
		// Single Value Parsing
		{
			static StringViewIMap< ParseMethod > parseMethods{
				{ CSTRING_VIEW( "count" ), &CPrimitiveTemplate::ParseCount },
				{ CSTRING_VIEW( "life" ), &CPrimitiveTemplate::ParseLife },
				{ CSTRING_VIEW( "delay" ), &CPrimitiveTemplate::ParseDelay },
				{ CSTRING_VIEW( "bounce" ), &CPrimitiveTemplate::ParseElasticity },
				{ CSTRING_VIEW( "intensity" ), &CPrimitiveTemplate::ParseElasticity },
				{ CSTRING_VIEW( "min" ), &CPrimitiveTemplate::ParseMin },
				{ CSTRING_VIEW( "max" ), &CPrimitiveTemplate::ParseMax },
				{ CSTRING_VIEW( "angle" ), &CPrimitiveTemplate::ParseAngle },
				{ CSTRING_VIEW( "angles" ), &CPrimitiveTemplate::ParseAngle },
				{ CSTRING_VIEW( "angleDelta" ), &CPrimitiveTemplate::ParseAngleDelta },
				{ CSTRING_VIEW( "velocity" ), &CPrimitiveTemplate::ParseVelocity },
				{ CSTRING_VIEW( "vel" ), &CPrimitiveTemplate::ParseVelocity },
				{ CSTRING_VIEW( "acceleration" ), &CPrimitiveTemplate::ParseAcceleration },
				{ CSTRING_VIEW( "accel" ), &CPrimitiveTemplate::ParseAcceleration },
				{ CSTRING_VIEW( "gravity" ), &CPrimitiveTemplate::ParseGravity },
				{ CSTRING_VIEW( "density" ), &CPrimitiveTemplate::ParseDensity },
				{ CSTRING_VIEW( "variance" ), &CPrimitiveTemplate::ParseVariance },
				{ CSTRING_VIEW( "origin" ), &CPrimitiveTemplate::ParseOrigin1 },
				{ CSTRING_VIEW( "origin2" ), &CPrimitiveTemplate::ParseOrigin2 },
				{ CSTRING_VIEW( "radius" ), &CPrimitiveTemplate::ParseRadius },
				{ CSTRING_VIEW( "height" ), &CPrimitiveTemplate::ParseHeight },
				{ CSTRING_VIEW( "wind" ), &CPrimitiveTemplate::ParseWindModifier },
				{ CSTRING_VIEW( "rotation" ), &CPrimitiveTemplate::ParseRotation },
				{ CSTRING_VIEW( "rotationDelta" ), &CPrimitiveTemplate::ParseRotationDelta },
				{ CSTRING_VIEW( "flags" ), &CPrimitiveTemplate::ParseFlags },
				{ CSTRING_VIEW( "flag" ), &CPrimitiveTemplate::ParseFlags },
				{ CSTRING_VIEW( "spawnFlags" ), &CPrimitiveTemplate::ParseSpawnFlags },
				{ CSTRING_VIEW( "spawnFlag" ), &CPrimitiveTemplate::ParseSpawnFlags },
			};
			auto pos = parseMethods.find( prop.GetName() );
			if( pos != parseMethods.end() )
			{
				ParseMethod method = pos->second;
				( this->*method )( prop.GetTopValue() );
				continue;
			}
		}
		// Property Parsing
		{
			using PropertyParseMethod = bool( CPrimitiveTemplate::* )( const CGPProperty& );
			static StringViewIMap< PropertyParseMethod > parseMethods{
				{ CSTRING_VIEW( "shaders" ), &CPrimitiveTemplate::ParseShaders },
				{ CSTRING_VIEW( "shader" ), &CPrimitiveTemplate::ParseShaders },
				{ CSTRING_VIEW( "models" ), &CPrimitiveTemplate::ParseModels },
				{ CSTRING_VIEW( "model" ), &CPrimitiveTemplate::ParseModels },
				{ CSTRING_VIEW( "sounds" ), &CPrimitiveTemplate::ParseSounds },
				{ CSTRING_VIEW( "sound" ), &CPrimitiveTemplate::ParseSounds },
				{ CSTRING_VIEW( "impactfx" ), &CPrimitiveTemplate::ParseImpactFxStrings },
				{ CSTRING_VIEW( "deathfx" ), &CPrimitiveTemplate::ParseDeathFxStrings },
				{ CSTRING_VIEW( "emitfx" ), &CPrimitiveTemplate::ParseEmitterFxStrings },
				{ CSTRING_VIEW( "playfx" ), &CPrimitiveTemplate::ParsePlayFxStrings },
			};
			auto pos = parseMethods.find( prop.GetName() );
			if( pos != parseMethods.end() )
			{
				PropertyParseMethod method = pos->second;
				( this->*method )( prop );
				continue;
			}
		}
		// Special Cases
		if( Q::stricmp( prop.GetName(), CSTRING_VIEW( "cullrange" ) ) == Q::Ordering::EQ )
		{
			mCullRange = Q::svtoi( prop.GetTopValue() );
			mCullRange *= mCullRange; // Square
		}
		else if( Q::stricmp( prop.GetName(), CSTRING_VIEW( "name" ) ) == Q::Ordering::EQ )
		{
			if( !prop.GetTopValue().empty() )
			{
				// just stash the descriptive name of the primitive
				std::size_t len = std::min< std::size_t >( prop.GetTopValue().size(), FX_MAX_PRIM_NAME - 1 );
				auto begin = prop.GetTopValue().begin();
				std::copy( begin, begin + len, &mName[ 0 ] );
				mName[ len ] = '\0';
			}
		}
		// Error
		else
		{
			theFxHelper.Print( "Unknown key parsing an effect primitive!\n" );
		}
	}

	for( auto& subGrp : grp.GetSubGroups() )
	{
		using GroupParseMethod = bool ( CPrimitiveTemplate::* )( const CGPGroup& );
		static StringViewIMap< GroupParseMethod > parseMethods{
			{ CSTRING_VIEW( "rgb" ), &CPrimitiveTemplate::ParseRGB },

			{ CSTRING_VIEW( "alpha" ), &CPrimitiveTemplate::ParseAlpha },

			{ CSTRING_VIEW( "size" ), &CPrimitiveTemplate::ParseSize },
			{ CSTRING_VIEW( "width" ), &CPrimitiveTemplate::ParseSize },

			{ CSTRING_VIEW( "size2" ), &CPrimitiveTemplate::ParseSize2 },
			{ CSTRING_VIEW( "width2" ), &CPrimitiveTemplate::ParseSize2 },

			{ CSTRING_VIEW( "length" ), &CPrimitiveTemplate::ParseLength },
			{ CSTRING_VIEW( "height" ), &CPrimitiveTemplate::ParseLength },
		};
		auto pos = parseMethods.find( subGrp.GetName() );
		if( pos == parseMethods.end() )
		{
			theFxHelper.Print( "Unknown group key parsing a particle!\n" );
		}
		else
		{
			GroupParseMethod method = pos->second;
			( this->*method )( subGrp );
		}
	}
	return true;
}
Ejemplo n.º 16
0
static sboolean Music_ParseMusic(CGenericParser2 &Parser, MusicData_t *MusicData, CGPGroup *pgMusicFiles, LPCSTR psMusicName, LPCSTR psMusicNameKey, MusicState_e eMusicState)
{
	sboolean bReturn = qfalse;

#ifdef _XBOX
	Z_SetNewDeleteTemporary(true);
#endif
	MusicFile_t MusicFile;
#ifdef _XBOX
	Z_SetNewDeleteTemporary(false);
#endif

	CGPGroup *pgMusicFile = pgMusicFiles->FindSubGroup(psMusicName);
	if (pgMusicFile)
	{
		// read subgroups...  
		//
		sboolean bEntryFound = qfalse;
		sboolean bExitFound  = qfalse;
		//
		// (read entry points first, so I can check exit points aren't too close in time)
		//
		CGPGroup *pEntryGroup = pgMusicFile->FindSubGroup(sKEY_ENTRY);
		if (pEntryGroup)
		{
			// read entry points...
			//
			for (CGPValue *pValue = pEntryGroup->GetPairs(); pValue; pValue = pValue->GetNext())
			{
				LPCSTR psKey	= pValue->GetName();
				LPCSTR psValue	= pValue->GetTopValue();

				//if (!strncmp(psKey,sKEY_MARKER,strlen(sKEY_MARKER)))	// for now, assume anything is a marker
				{
					MusicFile.MusicEntryTimes[psKey] = atof(psValue);
					bEntryFound = qtrue;						// harmless to keep setting
				}
			}
		}

		for (CGPGroup *pGroup = pgMusicFile->GetSubGroups(); pGroup; pGroup = pGroup->GetNext())
		{
			LPCSTR psGroupName = pGroup->GetName();

			if (!strcmp(psGroupName,sKEY_ENTRY))
			{
				// skip entry points, I've already read them in above
				//
			}
			else
			if (!strcmp(psGroupName,sKEY_EXIT))
			{
				int iThisExitPointIndex = MusicFile.MusicExitPoints.size();	// must eval this first, so unaffected by push_back etc
				//
				// read this set of exit points...
				//
				MusicExitPoint_t MusicExitPoint;
				for (CGPValue *pValue = pGroup->GetPairs(); pValue; pValue = pValue->GetNext())
				{
					LPCSTR psKey	= pValue->GetName();
					LPCSTR psValue	= pValue->GetTopValue();

					if (!strcmp(psKey,sKEY_NEXTFILE))
					{
						MusicExitPoint.sNextFile = psValue;
						bExitFound  = qtrue;	// harmless to keep setting
					}
					else
					if (!strcmp(psKey,sKEY_NEXTMARK))
					{
						MusicExitPoint.sNextMark = psValue;
					}
					else
					if (!strncmp(psKey,sKEY_TIME,strlen(sKEY_TIME)))
					{
						MusicExitTime_t MusicExitTime;
										MusicExitTime.fTime		= atof(psValue);
										MusicExitTime.iExitPoint= iThisExitPointIndex;

						// new check, don't keep this this exit point if it's within 1.5 seconds either way of an entry point...
						//
						sboolean bTooCloseToEntryPoint = qfalse;
						for (MusicEntryTimes_t::iterator itEntryTimes = MusicFile.MusicEntryTimes.begin(); itEntryTimes != MusicFile.MusicEntryTimes.end(); ++itEntryTimes)
						{
							float fThisEntryTime = (*itEntryTimes).second;

							if (Q_fabs(fThisEntryTime - MusicExitTime.fTime) < 1.5f)
							{
//								bTooCloseToEntryPoint = qtrue;	// not sure about this, ignore for now
								break;
							}
						}
						if (!bTooCloseToEntryPoint)
						{
#ifdef _XBOX
							Z_SetNewDeleteTemporary(true);
#endif
							MusicFile.MusicExitTimes.push_back(MusicExitTime);
#ifdef _XBOX
							Z_SetNewDeleteTemporary(false);
#endif
						}
					}
				}

#ifdef _XBOX
				Z_SetNewDeleteTemporary(true);
#endif
				MusicFile.MusicExitPoints.push_back(MusicExitPoint);
#ifdef _XBOX
				Z_SetNewDeleteTemporary(false);
#endif
				int iNumExitPoints = MusicFile.MusicExitPoints.size();

				// error checking...
				//
				switch (eMusicState)
				{
					case eBGRNDTRACK_EXPLORE:	
						if (iNumExitPoints > iMAX_EXPLORE_TRANSITIONS)
						{
							MUSIC_PARSE_ERROR( va("\"%s\" has > %d %s transitions defined!\n",psMusicName,iMAX_EXPLORE_TRANSITIONS,psMusicNameKey) );
							return qfalse;
						}
						break;

					case eBGRNDTRACK_ACTION:
						if (iNumExitPoints > iMAX_ACTION_TRANSITIONS)
						{
							MUSIC_PARSE_ERROR( va("\"%s\" has > %d %s transitions defined!\n",psMusicName,iMAX_ACTION_TRANSITIONS,psMusicNameKey) );
							return qfalse;
						}
						break;

					case eBGRNDTRACK_BOSS:
					case eBGRNDTRACK_DEATH:

						MUSIC_PARSE_ERROR( va("\"%s\" has %s transitions defined, this is not allowed!\n",psMusicName,psMusicNameKey) );
						break;					
				}
			}
		}

		// for now, assume everything was ok unless some obvious things are missing...
		//
		bReturn = qtrue;

		if (eMusicState != eBGRNDTRACK_BOSS && eMusicState != eBGRNDTRACK_DEATH)	// boss & death pieces can omit entry/exit stuff
		{
			if (!bEntryFound)
			{
				MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\" in group \"%s\"\n",sKEY_ENTRY,psMusicName));
				bReturn = qfalse;
			}
			if (!bExitFound)
			{
				MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\" in group \"%s\"\n",sKEY_EXIT,psMusicName));
				bReturn = qfalse;
			}
		}
	}
	else
	{
		MUSIC_PARSE_ERROR(va("Unable to find musicfiles entry \"%s\"\n",psMusicName));
	}

	if (bReturn)
	{
		MusicFile.sFileNameBase  = psMusicName; 
		(*MusicData)[ psMusicNameKey ] = MusicFile;
	}

	return bReturn;
}
Ejemplo n.º 17
0
/************************************************************************************************
 * CRMManager::LoadMission
 *	Loads the mission using the mission name stored in the ar_mission cvar
 *
 * inputs:
 *	none
 *
 * return:
 *	none
 *
 ************************************************************************************************/
bool CRMManager::LoadMission ( qboolean IsServer )
{
	char	instances[MAX_QPATH];
	char	mission[MAX_QPATH];
	char	course[MAX_QPATH];
	char	map[MAX_QPATH];
	char	temp[MAX_QPATH];

#ifndef FINAL_BUILD
	Com_Printf ("--------- Random Mission Manager ---------\n\n");
	Com_Printf ("RMG version : 1.01\n\n");
#endif

	if (!mTerrain)
	{
		return false;
	}

	// Grab the arioche variables
	Cvar_VariableStringBuffer("rmg_usetimelimit", temp, MAX_QPATH);
	if (Q_stricmp(temp, "yes") == 0)
	{
		mUseTimeLimit = true;
	}
	Cvar_VariableStringBuffer("rmg_instances", instances, MAX_QPATH);
	Cvar_VariableStringBuffer("RMG_mission", temp, MAX_QPATH);
	Cvar_VariableStringBuffer("rmg_map", map, MAX_QPATH);
	Com_sprintf(mission, sizeof(mission), "%s_%s", temp, map);
	Cvar_VariableStringBuffer("rmg_course", course, MAX_QPATH);

	// dump existing mission, if any
	if (mMission)
	{
		delete mMission;
		mMission = NULL;
	}

	// Create a new mission file	
	mMission = new CRMMission ( mTerrain );

	if ( IsServer )
	{
		// Load the mission using the arioche variables
		if ( !mMission->Load ( mission, instances, course ) )
		{
			return false;
		}
	
		// set the names of the teams 
		CGenericParser2		parser;
		CGPGroup*			root;

		Cvar_VariableStringBuffer("RMG_terrain", temp, MAX_QPATH);

		// Create the parser for the mission file
		if(Com_ParseTextFile(va("ext_data/rmg/%s.teams", temp), parser))
		{
			root = parser.GetBaseParseGroup()->GetSubGroups();
			if (0 == stricmp(root->GetName(), "teams"))
			{
				/*
				SV_SetConfigstring( CS_GAMETYPE_REDTEAM, root->FindPairValue ( "red", "marine" ));
				SV_SetConfigstring( CS_GAMETYPE_BLUETEAM, root->FindPairValue ( "blue", "thug" ));
				*/
				//rwwFIXMEFIXME: Do we care about this?
			}
			parser.Clean();
		}
	}

	// Must have a valid landscape before we can spawn the mission
	assert ( mLandScape );

#ifndef FINAL_BUILD
	Com_Printf ("------------------------------------------\n");
#endif

	return true;
}