/************************************************************************************************ * 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()); }
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); }
/************************************************************************************************ * 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; }
// 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; }
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; }
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; }
/************************************************************************************************ * 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; }