/************************************************************************************************
 * 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());
}
Esempio n. 2
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);
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}