Пример #1
0
/*
====================
CM_CreateShaderTextHash
=====================
*/
void CM_CreateShaderTextHash(void)
{
	const char			*p;
	qboolean			hasNewLines;
	char				*token;
	CCMShaderText		*shader;

	p = shaderText;
	// look for label
	while (p) 
	{
		p = SkipWhitespace(p, &hasNewLines);
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			break;
		}
		shader = new CCMShaderText(token, p);
		shaderTextTable.insert(shader);

		SkipBracedSection(&p);
	}
}
Пример #2
0
void NPC_PrecacheAnimationCFG( const char *NPC_type )
{
	char	filename[MAX_QPATH];
	const char	*token;
	const char	*value;
	const char	*p;
	int		junk;

	if ( !Q_stricmp( "random", NPC_type ) )
	{//sorry, can't precache a random just yet
		return;
	}

	p = NPCParms;
	COM_BeginParseSession();

	// look for the right NPC
	while ( p ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{
			return;
		}

		if ( !Q_stricmp( token, NPC_type ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}

	if ( !p ) 
	{
		return;
	}

	if ( G_ParseLiteral( &p, "{" ) ) 
	{
		return;
	}

	// parse the NPC info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPC_type );
			return;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		// legsmodel
		if ( !Q_stricmp( token, "legsmodel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			//must copy data out of this pointer into a different part of memory because the funcs we're about to call will call COM_ParseExt
			Q_strncpyz( filename, value, sizeof( filename ), qtrue );
			G_ParseAnimFileSet( filename, filename, &junk );
			return;
		}

		// playerModel
		if ( !Q_stricmp( token, "playerModel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			char	animName[MAX_QPATH];
			char	*GLAName;
			char	*slash = NULL;
			char	*strippedName;
			
			int handle = gi.G2API_PrecacheGhoul2Model( va( "models/players/%s/model.glm", value ) );
			if ( handle > 0 )//FIXME: isn't 0 a valid handle?
			{
				GLAName = gi.G2API_GetAnimFileNameIndex( handle );
				if ( GLAName )
				{
					Q_strncpyz( animName, GLAName, sizeof( animName ), qtrue );
					slash = strrchr( animName, '/' );
					if ( slash )
					{
						*slash = 0;
					}
					strippedName = COM_SkipPath( animName );

					//must copy data out of this pointer into a different part of memory because the funcs we're about to call will call COM_ParseExt
					Q_strncpyz( filename, value, sizeof( filename ), qtrue );
					G_ParseAnimFileSet( value, strippedName, &junk );//qfalse );
					//FIXME: still not precaching the animsounds.cfg?
					return;
				}
			}
		}
	}
}
Пример #3
0
qboolean NPC_ParseParms( const char *NPCName, gentity_t *NPC ) 
{
	const char	*token;
	const char	*value;
	const char	*p;
	int		n;
	float	f;
	char	*patch;
	char	sound[MAX_QPATH];
	char	playerModel[MAX_QPATH];
	char	customSkin[MAX_QPATH];
	clientInfo_t	*ci = &NPC->client->clientInfo;
	renderInfo_t	*ri = &NPC->client->renderInfo;
	gNPCstats_t		*stats = NULL;
	qboolean	md3Model = qtrue;
	char	surfOff[1024];
	char	surfOn[1024];

	strcpy(customSkin,"default");
	if ( !NPCName || !NPCName[0]) 
	{
		NPCName = "Player";
	}

	if ( NPC->NPC )
	{
		stats = &NPC->NPC->stats;
/*
	NPC->NPC->allWeaponOrder[0]	= WP_BRYAR_PISTOL;
	NPC->NPC->allWeaponOrder[1]	= WP_SABER;
	NPC->NPC->allWeaponOrder[2]	= WP_IMOD;
	NPC->NPC->allWeaponOrder[3]	= WP_SCAVENGER_RIFLE;
	NPC->NPC->allWeaponOrder[4]	= WP_TRICORDER;
	NPC->NPC->allWeaponOrder[6]	= WP_NONE;
	NPC->NPC->allWeaponOrder[6]	= WP_NONE;
	NPC->NPC->allWeaponOrder[7]	= WP_NONE;
*/
		// fill in defaults
		stats->aggression	= 3;
		stats->aim			= 3;
		stats->earshot		= 1024;
		stats->evasion		= 3;
		stats->hfov			= 90;
		stats->intelligence	= 3;
		stats->move			= 3;
		stats->reactions	= 3;
		stats->vfov			= 60;
		stats->vigilance	= 0.1f;
		stats->visrange		= 1024;

		stats->health		= 0;

		stats->moveType		= MT_RUNJUMP;
		stats->yawSpeed		= 90;
		stats->walkSpeed	= 90;
		stats->runSpeed		= 300;
		stats->acceleration	= 15;//Increase/descrease speed this much per frame (20fps)
	}
	else
	{
		stats = NULL;
	}

	Q_strncpyz( ci->name, NPCName, sizeof( ci->name ) );
	
	NPC->playerModel = -1;
	
	//Set defaults
	//FIXME: should probably put default torso and head models, but what about enemies
	//that don't have any- like Stasis?
	//Q_strncpyz( ri->headModelName,	DEFAULT_HEADMODEL,  sizeof(ri->headModelName),	qtrue);
	//Q_strncpyz( ri->torsoModelName, DEFAULT_TORSOMODEL, sizeof(ri->torsoModelName),	qtrue);
	//Q_strncpyz( ri->legsModelName,	DEFAULT_LEGSMODEL,  sizeof(ri->legsModelName),	qtrue);
	memset( ri->headModelName, 0, sizeof( ri->headModelName ) );
	memset( ri->torsoModelName, 0, sizeof( ri->torsoModelName ) );
	memset( ri->legsModelName, 0, sizeof( ri->legsModelName ) );
	//FIXME: should we have one for weapon too?
	memset( (char *)surfOff, 0, sizeof(surfOff) );
	memset( (char *)surfOn, 0, sizeof(surfOn) );
	
	/*
	ri->headYawRangeLeft = 50;
	ri->headYawRangeRight = 50;
	ri->headPitchRangeUp = 40;
	ri->headPitchRangeDown = 50;
	ri->torsoYawRangeLeft = 60;
	ri->torsoYawRangeRight = 60;
	ri->torsoPitchRangeUp = 30;
	ri->torsoPitchRangeDown = 70;
	*/

	ri->headYawRangeLeft = 80;
	ri->headYawRangeRight = 80;
	ri->headPitchRangeUp = 45;
	ri->headPitchRangeDown = 45;
	ri->torsoYawRangeLeft = 60;
	ri->torsoYawRangeRight = 60;
	ri->torsoPitchRangeUp = 30;
	ri->torsoPitchRangeDown = 50;

	VectorCopy(playerMins, NPC->mins);
	VectorCopy(playerMaxs, NPC->maxs);
	NPC->client->crouchheight = CROUCH_MAXS_2;
	NPC->client->standheight = DEFAULT_MAXS_2;

	NPC->client->dismemberProbHead = 100;
	NPC->client->dismemberProbArms = 100;
	NPC->client->dismemberProbHands = 100;
	NPC->client->dismemberProbWaist = 100;
	NPC->client->dismemberProbLegs = 100;
	

	if ( !Q_stricmp( "random", NPCName ) )
	{//Randomly assemble a starfleet guy
		NPC_BuildRandom( NPC );
	}
	else
	{
		p = NPCParms;
		COM_BeginParseSession();

		// look for the right NPC
		while ( p ) 
		{
			token = COM_ParseExt( &p, qtrue );
			if ( token[0] == 0 )
			{
				return qfalse;
			}

			if ( !Q_stricmp( token, NPCName ) ) 
			{
				break;
			}

			SkipBracedSection( &p );
		}
		if ( !p ) 
		{
			return qfalse;
		}

		if ( G_ParseLiteral( &p, "{" ) ) 
		{
			return qfalse;
		}
			
		// parse the NPC info block
		while ( 1 ) 
		{
			token = COM_ParseExt( &p, qtrue );
			if ( !token[0] ) 
			{
				gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPCName );
				return qfalse;
			}

			if ( !Q_stricmp( token, "}" ) ) 
			{
				break;
			}
	//===MODEL PROPERTIES===========================================================
			// headmodel
			if ( !Q_stricmp( token, "headmodel" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}

				if(!Q_stricmp("none", value))
				{
					ri->headModelName[0] = NULL;
					//Zero the head clamp range so the torso & legs don't lag behind
					ri->headYawRangeLeft = 
					ri->headYawRangeRight = 
					ri->headPitchRangeUp = 
					ri->headPitchRangeDown = 0;
				}
				else
				{
					Q_strncpyz( ri->headModelName, value, sizeof(ri->headModelName), qtrue);
				}
				continue;
			}
			
			// torsomodel
			if ( !Q_stricmp( token, "torsomodel" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}

				if(!Q_stricmp("none", value))
				{
					ri->torsoModelName[0] = NULL;
					//Zero the torso clamp range so the legs don't lag behind
					ri->torsoYawRangeLeft = 
					ri->torsoYawRangeRight = 
					ri->torsoPitchRangeUp = 
					ri->torsoPitchRangeDown = 0;
				}
				else
				{
					Q_strncpyz( ri->torsoModelName, value, sizeof(ri->torsoModelName), qtrue);
				}
				continue;
			}

			// legsmodel
			if ( !Q_stricmp( token, "legsmodel" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				Q_strncpyz( ri->legsModelName, value, sizeof(ri->legsModelName), qtrue);			
				//Need to do this here to get the right index
				G_ParseAnimFileSet( ri->legsModelName, ri->legsModelName, &ci->animFileIndex );
				continue;
			}

			// playerModel
			if ( !Q_stricmp( token, "playerModel" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				Q_strncpyz( playerModel, value, sizeof(playerModel), qtrue);			
				md3Model = qfalse;
				continue;
			}
			
			// customSkin
			if ( !Q_stricmp( token, "customSkin" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				Q_strncpyz( customSkin, value, sizeof(customSkin), qtrue);			
				continue;
			}

			// surfOff
			if ( !Q_stricmp( token, "surfOff" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				if ( surfOff[0] )
				{
					strncat( (char *)surfOff, ",", sizeof(surfOff) );
					strncat( (char *)surfOff, value, sizeof(surfOff) );
				}
				else
				{
					Q_strncpyz( surfOff, value, sizeof(surfOff), qtrue);
				}
				continue;
			}
			
			// surfOn
			if ( !Q_stricmp( token, "surfOn" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				if ( surfOn[0] )
				{
					strncat( (char *)surfOn, ",", sizeof(surfOn) );
					strncat( (char *)surfOn, value, sizeof(surfOn) );
				}
				else
				{
					Q_strncpyz( surfOn, value, sizeof(surfOn), qtrue);
				}
				continue;
			}
			
			//headYawRangeLeft
			if ( !Q_stricmp( token, "headYawRangeLeft" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->headYawRangeLeft = n;
				continue;
			}

			//headYawRangeRight
			if ( !Q_stricmp( token, "headYawRangeRight" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->headYawRangeRight = n;
				continue;
			}

			//headPitchRangeUp
			if ( !Q_stricmp( token, "headPitchRangeUp" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->headPitchRangeUp = n;
				continue;
			}
			
			//headPitchRangeDown
			if ( !Q_stricmp( token, "headPitchRangeDown" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->headPitchRangeDown = n;
				continue;
			}

			//torsoYawRangeLeft
			if ( !Q_stricmp( token, "torsoYawRangeLeft" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->torsoYawRangeLeft = n;
				continue;
			}

			//torsoYawRangeRight
			if ( !Q_stricmp( token, "torsoYawRangeRight" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->torsoYawRangeRight = n;
				continue;
			}

			//torsoPitchRangeUp
			if ( !Q_stricmp( token, "torsoPitchRangeUp" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->torsoPitchRangeUp = n;
				continue;
			}

			//torsoPitchRangeDown
			if ( !Q_stricmp( token, "torsoPitchRangeDown" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				ri->torsoPitchRangeDown = n;
				continue;
			}

			// Uniform XYZ scale
			if ( !Q_stricmp( token, "scale" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if (n != 100)
				{
					NPC->s.modelScale[0] = NPC->s.modelScale[1] = NPC->s.modelScale[2] = n/100.0f;
				}
				continue;
			}

			//X scale
			if ( !Q_stricmp( token, "scaleX" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if (n != 100)
				{
					NPC->s.modelScale[0] = n/100.0f;
				}
				continue;
			}

			//Y scale
			if ( !Q_stricmp( token, "scaleY" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if (n != 100)
				{
					NPC->s.modelScale[1] = n/100.0f;
				}
				continue;
			}

			//Z scale
			if ( !Q_stricmp( token, "scaleZ" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if (n != 100)
				{
					NPC->s.modelScale[2] = n/100.0f;
				}
				continue;
			}

	//===AI STATS=====================================================================
			// aggression
			if ( !Q_stricmp( token, "aggression" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 1 || n > 5 ) {
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->aggression = n;
				}
				continue;
			}

			// aim
			if ( !Q_stricmp( token, "aim" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 1 || n > 5 ) {
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->aim = n;
				}
				continue;
			}

			// earshot
			if ( !Q_stricmp( token, "earshot" ) ) {
				if ( COM_ParseFloat( &p, &f ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( f < 0.0f ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->earshot = f;
				}
				continue;
			}

			// evasion
			if ( !Q_stricmp( token, "evasion" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 1 || n > 5 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->evasion = n;
				}
				continue;
			}

			// hfov
			if ( !Q_stricmp( token, "hfov" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 30 || n > 180 ) {
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->hfov = n;// / 2;	//FIXME: Why was this being done?!
				}
				continue;
			}

			// intelligence
			if ( !Q_stricmp( token, "intelligence" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 1 || n > 5 ) {
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->intelligence = n;
				}
				continue;
			}
			
			// move
			if ( !Q_stricmp( token, "move" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 1 || n > 5 ) {
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->move = n;
				}
				continue;
			}

			// reactions
			if ( !Q_stricmp( token, "reactions" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 1 || n > 5 ) {
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->reactions = n;
				}
				continue;
			}

			// shootDistance
			if ( !Q_stricmp( token, "saberColor" ) ) {
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				if ( NPC->client )
				{
					NPC->client->ps.saberColor = TranslateSaberColor( value );
				}
				continue;
			}

			// shootDistance
			if ( !Q_stricmp( token, "shootDistance" ) ) {
				if ( COM_ParseFloat( &p, &f ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( f < 0.0f ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->shootDistance = f;
				}
				continue;
			}

			// shootDistance
			if ( !Q_stricmp( token, "health" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->health = n;
				}
				continue;
			}

			// vfov
			if ( !Q_stricmp( token, "vfov" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 30 || n > 180 ) {
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->vfov = n / 2;
				}
				continue;
			}

			// vigilance
			if ( !Q_stricmp( token, "vigilance" ) ) {
				if ( COM_ParseFloat( &p, &f ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( f < 0.0f ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->vigilance = f;
				}
				continue;
			}

			// visrange
			if ( !Q_stricmp( token, "visrange" ) ) {
				if ( COM_ParseFloat( &p, &f ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( f < 0.0f ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->visrange = f;
				}
				continue;
			}

			// race
	//		if ( !Q_stricmp( token, "race" ) ) 
	//		{
	//			if ( COM_ParseString( &p, &value ) ) 
	//			{
	//				continue;
	//			}
	//			NPC->client->race = TranslateRaceName(value);
	//			continue;
	//		}

			// rank
			if ( !Q_stricmp( token, "rank" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->NPC->rank = TranslateRankName(value);
				}
				continue;
			}

			// fullName
			if ( !Q_stricmp( token, "fullName" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				NPC->fullName = G_NewString(value);
				continue;
			}

			// playerTeam
			if ( !Q_stricmp( token, "playerTeam" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				NPC->client->playerTeam = TranslateTeamName(value);
				continue;
			}

			// enemyTeam
			if ( !Q_stricmp( token, "enemyTeam" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				NPC->client->enemyTeam = TranslateTeamName(value);
				continue;
			}

			// class
			if ( !Q_stricmp( token, "class" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}
				NPC->client->NPC_class = TranslateClassName(value);
				continue;
			}

			// dismemberment probability for head
			if ( !Q_stricmp( token, "dismemberProbHead" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->client->dismemberProbHead = n;
				}
				continue;
			}

			// dismemberment probability for arms
			if ( !Q_stricmp( token, "dismemberProbArms" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->client->dismemberProbArms = n;
				}
				continue;
			}

			// dismemberment probability for hands
			if ( !Q_stricmp( token, "dismemberProbHands" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->client->dismemberProbHands = n;
				}
				continue;
			}

			// dismemberment probability for waist
			if ( !Q_stricmp( token, "dismemberProbWaist" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->client->dismemberProbWaist = n;
				}
				continue;
			}

			// dismemberment probability for legs
			if ( !Q_stricmp( token, "dismemberProbLegs" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->client->dismemberProbLegs = n;
				}
				continue;
			}

	//===MOVEMENT STATS============================================================
			
			if ( !Q_stricmp( token, "width" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					continue;
				}

				NPC->mins[0] = NPC->mins[1] = -n;
				NPC->maxs[0] = NPC->maxs[1] = n;
				continue;
			}

			if ( !Q_stricmp( token, "height" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					continue;
				}

				NPC->mins[2] = DEFAULT_MINS_2;//Cannot change
				NPC->maxs[2] = NPC->client->standheight = n + DEFAULT_MINS_2;
				NPC->radius = n;
				continue;
			}

			if ( !Q_stricmp( token, "crouchheight" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					continue;
				}

				NPC->client->crouchheight = n + DEFAULT_MINS_2;
				continue;
			}

			if ( !Q_stricmp( token, "movetype" ) ) 
			{
				if ( COM_ParseString( &p, &value ) ) 
				{
					continue;
				}

				if ( NPC->NPC )
				{
					stats->moveType = (movetype_t)MoveTypeNameToEnum(value);
				}
				continue;
			}
				
			// yawSpeed
			if ( !Q_stricmp( token, "yawSpeed" ) ) {
				if ( COM_ParseInt( &p, &n ) ) {
					SkipRestOfLine( &p );
					continue;
				}
				if ( n <= 0) {
					gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->yawSpeed = ((float)(n));
				}
				continue;
			}

			// walkSpeed
			if ( !Q_stricmp( token, "walkSpeed" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->walkSpeed = n;
				}
				continue;
			}
			
			//runSpeed
			if ( !Q_stricmp( token, "runSpeed" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->runSpeed = n;
				}
				continue;
			}

			//acceleration
			if ( !Q_stricmp( token, "acceleration" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < 0 ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					stats->acceleration = n;
				}
				continue;
			}
	//===MISC===============================================================================
			// default behavior
			if ( !Q_stricmp( token, "behavior" ) ) 
			{
				if ( COM_ParseInt( &p, &n ) ) 
				{
					SkipRestOfLine( &p );
					continue;
				}
				if ( n < BS_DEFAULT || n >= NUM_BSTATES ) 
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad %s in NPC '%s'\n", token, NPCName );
					continue;
				}
				if ( NPC->NPC )
				{
					NPC->NPC->defaultBehavior = (bState_t)(n);
				}
				continue;
			}

			// snd
			if ( !Q_stricmp( token, "snd" ) ) {
				if ( COM_ParseString( &p, &value ) ) {
					continue;
				}
				if ( !(NPC->svFlags&SVF_NO_BASIC_SOUNDS) )
				{
					//FIXME: store this in some sound field or parse in the soundTable like the animTable...
					Q_strncpyz( sound, value, sizeof( sound ) );
					patch = strstr( sound, "/" );
					if ( patch ) 
					{
						*patch = 0;
					}
					ci->customBasicSoundDir = G_NewString( sound );
				}
				continue;
			}

			// sndcombat
			if ( !Q_stricmp( token, "sndcombat" ) ) {
				if ( COM_ParseString( &p, &value ) ) {
					continue;
				}
				if ( !(NPC->svFlags&SVF_NO_COMBAT_SOUNDS) )
				{
					//FIXME: store this in some sound field or parse in the soundTable like the animTable...
					Q_strncpyz( sound, value, sizeof( sound ) );
					patch = strstr( sound, "/" );
					if ( patch ) 
					{
						*patch = 0;
					}
					ci->customCombatSoundDir = G_NewString( sound );
				}
				continue;
			}
			
			// sndextra
			if ( !Q_stricmp( token, "sndextra" ) ) {
				if ( COM_ParseString( &p, &value ) ) {
					continue;
				}
				if ( !(NPC->svFlags&SVF_NO_EXTRA_SOUNDS) )
				{
					//FIXME: store this in some sound field or parse in the soundTable like the animTable...
					Q_strncpyz( sound, value, sizeof( sound ) );
					patch = strstr( sound, "/" );
					if ( patch ) 
					{
						*patch = 0;
					}
					ci->customExtraSoundDir = G_NewString( sound );
				}
				continue;
			}

			// sndjedi
			if ( !Q_stricmp( token, "sndjedi" ) ) {
				if ( COM_ParseString( &p, &value ) ) {
					continue;
				}
				if ( !(NPC->svFlags&SVF_NO_EXTRA_SOUNDS) )
				{
					//FIXME: store this in some sound field or parse in the soundTable like the animTable...
					Q_strncpyz( sound, value, sizeof( sound ) );
					patch = strstr( sound, "/" );
					if ( patch ) 
					{
						*patch = 0;
					}
					ci->customJediSoundDir = G_NewString( sound );
				}
				continue;
			}

			gi.Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, NPCName );
			SkipRestOfLine( &p );
		}
	}

	ci->infoValid = qfalse;

/*
Ghoul2 Insert Start
*/
	if ( !md3Model )
	{
		NPC->weaponModel = -1;
		G_SetG2PlayerModel( NPC, playerModel, customSkin, surfOff, surfOn );
	}
/*
Ghoul2 Insert End
*/
	if(	NPCsPrecached )
	{//Spawning in after initial precache, our models are precached, we just need to set our clientInfo
		CG_RegisterClientModels( NPC->s.number );
		CG_RegisterNPCCustomSounds( ci );
		CG_RegisterNPCEffects( NPC->client->playerTeam );
	}

	return qtrue;
}
Пример #4
0
qboolean UI_SaberParseParm( const char *saberName, const char *parmname, char *saberData ) 
{
	const char	*token;
	const char	*value;
	const char	*p;

	if ( !saberName || !saberName[0] ) 
	{
		return qfalse;
	}

	//try to parse it out
	p = SaberParms;
	COM_BeginParseSession();

	// look for the right saber
	while ( p )
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{
			return qfalse;
		}

		if ( !Q_stricmp( token, saberName ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}
	if ( !p ) 
	{
		return qfalse;
	}

	if ( UI_ParseLiteral( &p, "{" ) ) 
	{
		return qfalse;
	}
		
	// parse the saber info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			ui.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", saberName );
			return qfalse;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		if ( !Q_stricmp( token, parmname ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			strcpy( saberData, value );
			return qtrue;
		}

		SkipRestOfLine( &p );
		continue;
	}

	return qfalse;
}
Пример #5
0
/*
=================
CM_ParseShader

The current text pointer is at the explicit text definition of the
shader.  Parse it into the global shader variable.

This extracts all the info from the shader required for physics and collision
It is designed to *NOT* load any image files and not require any of the renderer to 
be initialised.
=================
*/
static void CM_ParseShader( CCMShader *shader, const char **text )
{
	char	*token;

	token = COM_ParseExt( text, qtrue );
	if ( token[0] != '{' )
	{
		Com_Printf( S_COLOR_YELLOW "WARNING: expecting '{', found '%s' instead in shader '%s'\n", token, shader->shader );
		return;
	}

	while ( true )
	{
		token = COM_ParseExt( text, qtrue );
		if ( !token[0] )
		{
			Com_Printf( S_COLOR_YELLOW "WARNING: no concluding '}' in shader %s\n", shader->shader );
			return;
		}

		// end of shader definition
		if ( token[0] == '}' )
		{
			break;
		}
		// stage definition
		else if ( token[0] == '{' )
		{
			SkipBracedSection( text );
			continue;
		}
		// material deprecated as of 11 Jan 01
		// material undeprecated as of 7 May 01 - q3map_material deprecated
		else if ( !Q_stricmp( token, "material" ) || !Q_stricmp( token, "q3map_material" ) )
		{
			SV_ParseMaterial( shader, text );
		}
		// sun parms
		// q3map_sun deprecated as of 11 Jan 01
		else if ( !Q_stricmp( token, "sun" ) || !Q_stricmp( token, "q3map_sun" ) ) 
		{
//			float	a, b;

			token = COM_ParseExt( text, qfalse );
//			shader->sunLight[0] = atof( token );
			token = COM_ParseExt( text, qfalse );
//			shader->sunLight[1] = atof( token );
			token = COM_ParseExt( text, qfalse );
//			shader->sunLight[2] = atof( token );
			
//			VectorNormalize( shader->sunLight );

			token = COM_ParseExt( text, qfalse );
//			a = atof( token );
//			VectorScale( shader->sunLight, a, shader->sunLight);

			token = COM_ParseExt( text, qfalse );
//			a = DEG2RAD(atof( token ));

			token = COM_ParseExt( text, qfalse );
//			b = DEG2RAD(atof( token ));

//			shader->sunDirection[0] = cos( a ) * cos( b );
//			shader->sunDirection[1] = sin( a ) * cos( b );
//			shader->sunDirection[2] = sin( b );
		}
		else if ( !Q_stricmp( token, "surfaceParm" ) ) 
		{
			SV_ParseSurfaceParm( shader, text );
			continue;
		}
		else if ( !Q_stricmp( token, "fogParms" ) ) 
		{
			vec3_t				fogColor;
			if ( !CM_ParseVector( shader, text, 3, fogColor ) ) 
			{
				return;
			}

			token = COM_ParseExt( text, qfalse );
			if ( !token[0] ) 
			{
				Com_Printf( S_COLOR_YELLOW "WARNING: missing parm for 'fogParms' keyword in shader '%s'\n", shader->shader );
				continue;
			}
//			shader->depthForOpaque = atof( token );

			// skip any old gradient directions
			SkipRestOfLine( (const char **)text );
			continue;
		}
	}
	return;
}
Пример #6
0
/*
void NPC_Precache ( char *NPCName )

Precaches NPC skins, tgas and md3s.

*/
void NPC_Precache ( gentity_t *spawner )
{
	clientInfo_t	ci={0};
	renderInfo_t	ri={0};
	team_t			playerTeam = TEAM_FREE;
	char	*token;
	char	*value;
	char	*p;
	char	*patch;
	char	sound[MAX_QPATH];

	if ( !Q_stricmp( "random", spawner->NPC_type ) )
	{//sorry, can't precache a random just yet
		return;
	}

	p = NPCParms;
	COM_BeginParseSession();

	// look for the right NPC
	while ( p ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
			return;

		if ( !Q_stricmp( token, spawner->NPC_type ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}

	if ( !p ) 
	{
		return;
	}

	if ( G_ParseLiteral( &p, "{" ) ) 
	{
		return;
	}

	// parse the NPC info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", spawner->NPC_type );
			return;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		// headmodel
		if ( !Q_stricmp( token, "headmodel" ) ) 
		{
			if ( G_ParseString( &p, &value ) ) 
			{
				continue;
			}

			if(!Q_stricmp("none", value))
			{
			}
			else
			{
				Q_strncpyz( ri.headModelName, value, sizeof(ri.headModelName), qtrue);
			}
			continue;
		}
		
		// torsomodel
		if ( !Q_stricmp( token, "torsomodel" ) ) 
		{
			if ( G_ParseString( &p, &value ) ) 
			{
				continue;
			}

			if(!Q_stricmp("none", value))
			{
			}
			else
			{
				Q_strncpyz( ri.torsoModelName, value, sizeof(ri.torsoModelName), qtrue);
			}
			continue;
		}

		// legsmodel
		if ( !Q_stricmp( token, "legsmodel" ) ) 
		{
			if ( G_ParseString( &p, &value ) ) 
			{
				continue;
			}
			Q_strncpyz( ri.legsModelName, value, sizeof(ri.legsModelName), qtrue);			
			continue;
		}

		// playerTeam
		if ( !Q_stricmp( token, "playerTeam" ) ) 
		{
			if ( G_ParseString( &p, &value ) ) 
			{
				continue;
			}
			playerTeam = TranslateTeamName(value);
			continue;
		}

		// snd
		if ( !Q_stricmp( token, "snd" ) ) {
			if ( G_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_BASIC_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customBasicSoundDir = G_NewString( sound );
			}
			continue;
		}

		// sndcombat
		if ( !Q_stricmp( token, "sndcombat" ) ) {
			if ( G_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_COMBAT_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customCombatSoundDir = G_NewString( sound );
			}
			continue;
		}
		
		// sndextra
		if ( !Q_stricmp( token, "sndextra" ) ) {
			if ( G_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_EXTRA_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customExtraSoundDir = G_NewString( sound );
			}
			continue;
		}

		// sndscav
		if ( !Q_stricmp( token, "sndscav" ) ) {
			if ( G_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_SCAV_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customScavSoundDir = G_NewString( sound );
			}
			continue;
		}
	}

	CG_RegisterClientRenderInfo( &ci, &ri );
	CG_RegisterNPCCustomSounds( &ci );
	CG_RegisterNPCEffects( playerTeam );
	//FIXME: precache the beam-in/exit sound and effect if not silentspawn
	//FIXME: Look for a "sounds" directory and precache death, pain, alert sounds
}
Пример #7
0
static qboolean CG_ParseLensFlareEffect(char** p, lensFlareEffect_t* lfe) {
	char* token;
	char* name;

#if LFDEBUG
	CG_LoadingString("LF: CG_ParseLensFlareEffect()");
#endif
	ParseEffect:
	token = COM_Parse(p);
	if (!token[0]) {
		if (CG_PopFile()) {
			*p = lfbuf;
			goto ParseEffect;
		}
		return qfalse;
	}

	if (!Q_stricmp(token, "import")) {
		CG_PushFile("maps/import/", COM_Parse(p));
		goto ParseEffect;
	}

	if (!Q_stricmp(token, "sunparm")) {
		token = COM_Parse(p);
		Q_strncpyz(cgs.sunFlareEffect, token, sizeof(cgs.sunFlareEffect));

		token = COM_Parse(p);
		cgs.sunFlareYaw = atof(token);

		token = COM_Parse(p);
		cgs.sunFlarePitch = atof(token);

		token = COM_Parse(p);
		cgs.sunFlareDistance = atof(token);
		goto ParseEffect;
	}

	name = va("%s%s", lfNameBase, token);
	if (CG_FindLensFlareEffect(name)) {
		SkipBracedSection(p, 0);
		goto ParseEffect;
	}

	Q_strncpyz(lfe->name, name, sizeof(lfe->name));

	token = COM_Parse(p);
	if (Q_stricmp(token, "{")) {
		CG_Printf(S_COLOR_YELLOW "read '%s', expected '{' in '%s'\n", token, lfe->name);
		return qfalse;
	}

	// set non-zero default values
	lfe->range = 400;
	lfe->fadeAngle = 20;

	while (1) {
		token = COM_Parse(p);
		if (!token[0]) {
			CG_Printf(S_COLOR_YELLOW "unexpected end of lens flare effect '%s'\n", lfe->name);
			return qfalse;
		}

		if (!Q_stricmp(token, "}")) break;

		if (!Q_stricmp(token, "{")) {
			if (lfe->numLensFlares >= MAX_LENSFLARES_PER_EFFECT) {
				CG_Printf(S_COLOR_YELLOW "too many lensflares in '%s' (max=%d)\n", lfe->name, MAX_LENSFLARES_PER_EFFECT);
				return qfalse;
			}

			if (!CG_ParseLensFlare(p, &lfe->lensFlares[lfe->numLensFlares], lfe->name)) return qfalse;
			lfe->numLensFlares++;
		}
		else if (!Q_stricmp(token, "range")) {
			token = COM_Parse(p);
			lfe->range = atof(token);
			lfe->rangeSqr = Square(lfe->range);
		}
		else if (!Q_stricmp(token, "fadeAngle")) {
			token = COM_Parse(p);
			lfe->fadeAngle = Com_Clamp(0, 180, atof(token));
		}
		else {
			CG_Printf(S_COLOR_YELLOW "unexpected token '%s' in '%s'\n", token, lfe->name);
			return qfalse;
		}
	}

	CG_FinalizeLensFlareEffect(lfe);

	return qtrue;
}
Пример #8
0
/*
=================
CM_ParseShader

The current text pointer is at the explicit text definition of the
shader.  Parse it into the global shader variable.

This extracts all the info from the shader required for physics and collision
It is designed to *NOT* load any image files and not require any of the renderer to 
be initialised.
=================
*/
static void CM_ParseShader( CCMShader *shader, const char **text )
{
	char	*token;

	token = COM_ParseExt( text, qtrue );
	if ( token[0] != '{' )
	{
		Com_Printf( S_COLOR_YELLOW "WARNING: expecting '{', found '%s' instead in shader '%s'\n", token, shader->shader );
		return;
	}

	while ( true )
	{
		token = COM_ParseExt( text, qtrue );
		if ( !token[0] )
		{
			Com_Printf( S_COLOR_YELLOW "WARNING: no concluding '}' in shader %s\n", shader->shader );
			return;
		}

		// end of shader definition
		if ( token[0] == '}' )
		{
			break;
		}
		// stage definition
		else if ( token[0] == '{' )
		{
			SkipBracedSection( text );
			continue;
		}
		// material deprecated as of 11 Jan 01
		// material undeprecated as of 7 May 01 - q3map_material deprecated
		else if ( !Q_stricmp( token, "material" ) || !Q_stricmp( token, "q3map_material" ) )
		{
			SV_ParseMaterial( shader, text );
		}
		// sun parms
		// q3map_sun deprecated as of 11 Jan 01
		else if ( !Q_stricmp( token, "sun" ) || !Q_stricmp( token, "q3map_sun" ) ) 
		{
			float	a, b;

			token = COM_ParseExt( text, qfalse );
			shader->sunLight[0] = atof( token );
			token = COM_ParseExt( text, qfalse );
			shader->sunLight[1] = atof( token );
			token = COM_ParseExt( text, qfalse );
			shader->sunLight[2] = atof( token );
			
			VectorNormalize( shader->sunLight );

			token = COM_ParseExt( text, qfalse );
			a = atof( token );
			VectorScale( shader->sunLight, a, shader->sunLight);

			token = COM_ParseExt( text, qfalse );
			a = DEG2RAD(atof( token ));

			token = COM_ParseExt( text, qfalse );
			b = DEG2RAD(atof( token ));

			shader->sunDirection[0] = cos( a ) * cos( b );
			shader->sunDirection[1] = sin( a ) * cos( b );
			shader->sunDirection[2] = sin( b );
		}
		else if ( !Q_stricmp( token, "surfaceParm" ) ) 
		{
			SV_ParseSurfaceParm( shader, text );
			continue;
		}
		else if ( !Q_stricmp( token, "fogParms" ) ) 
		{
			if ( !CM_ParseVector( shader, text, 3, shader->fogColor ) ) 
			{
				return;
			}

			token = COM_ParseExt( text, qfalse );
			if ( !token[0] ) 
			{
				Com_Printf( S_COLOR_YELLOW "WARNING: missing parm for 'fogParms' keyword in shader '%s'\n", shader->shader );
				continue;
			}
			shader->depthForOpaque = atof( token );

			// skip any old gradient directions
			SkipRestOfLine( (const char **)text );
			continue;
		}
		else if ( !Q_stricmp( token, "damageShader" ) ) 
		{
			CCMShader	*damageShader;

			token = COM_ParseExt( text, qfalse );
			if ( !token[0] ) 
			{
				Com_Printf( S_COLOR_YELLOW "WARNING: missing parm for 'damageShader' keyword in shader '%s'\n", shader->shader );
				continue;
			}
			damageShader = CM_GetShaderInfo(token);
			if(damageShader)
			{
				shader->damageShaderNum = damageShader - cm.shaders;
			}

			token = COM_ParseExt( text, qfalse );
			if(token)
			{
				shader->damage = atof(token);
			}
			continue;
		}
		// 
		// location hit mesh load
		//
		else if ( !Q_stricmp( token, "hitLocation" ) )
		{
			// grab the filename of the hit location texture
			token = COM_ParseExt( text, qfalse );
			if ( !token[0] )
			{
				break;
			}
			Q_strncpyz(shader->hitLocation, token, MAX_QPATH);
			continue;
		}
		// 
		// location hit material mesh load
		//
		else if ( !Q_stricmp( token, "hitMaterial" ) )
		{
			// grab the filename of the hit location texture
			token = COM_ParseExt( text, qfalse );
			if ( !token[0] )
			{
				break;
			}
			Q_strncpyz(shader->hitMaterial, token, MAX_QPATH);
			continue;
		}
	}
	return;
}
Пример #9
0
qboolean BG_ParseRankNames( char* fileName, rankNames_t rankNames[] ) {
	fileHandle_t	f;
	int				file_len;
	char			charText[20000];
	char*			textPtr;
	char*			token;
	int				i = 0;

	file_len = trap_FS_FOpenFile( fileName, &f, FS_READ );

	if ( file_len<= 0 ) {
		return qfalse;
	}

	if ( file_len >= ( sizeof(charText) - 1) ) {
		Com_Printf( S_COLOR_RED "File length of %s is too long.\n", fileName );
	}

	memset( &charText, 0, sizeof( charText ) );
	memset( rankNames, 0, sizeof( rankNames ) );

	trap_FS_Read( charText, file_len, f );

	charText[file_len] = 0;

	trap_FS_FCloseFile( f );

	COM_BeginParseSession();

	textPtr = charText;

	token = COM_Parse( &textPtr );

	if ( !token[0] ) {
		Com_Printf( S_COLOR_RED "No data found in buffer: %s\n", fileName );
		return qfalse;
	}

	if ( Q_stricmpn( token, "{", 1 ) ) {
		Com_Printf( S_COLOR_RED "No beginning { found in %s\n", fileName );
		return qfalse;
	}

	//Parse out the default cell.  Default has no names anyway,
	//but in case a n00bie modder put names in anyway.
	SkipBracedSection( &textPtr );

	while( 1 ) {
		//lastPtr = textPtr;
		token = COM_Parse( &textPtr );
		if( !token[0] ) {
			break;
		}

		if ( i >= MAX_RANKS ) {
			break;
		}

		//If we hit an open brace (ie, assuming we hit the start of a new rank cell)
		if ( !Q_stricmpn( token, "{", 1 ) ) {
			while ( 1 ) {
				token = COM_Parse( &textPtr );
				if( !token[0] ) {
					break;
				}

				//We hit a MenuTexture entry, since this uses { symbols, we'll skip these to stop errors.
				if ( !Q_stricmpn( token, "MenuTexture", 11 ) ) {
					SkipRestOfLine( &textPtr );
					continue;
				}

				if ( !Q_stricmpn( token, "ConsoleName", 11) ) {
					if ( COM_ParseString( &textPtr, &token ) ) {
						continue;
					}

					Q_strncpyz( rankNames[i].consoleName, token, sizeof( rankNames[i].consoleName ) );

					continue;
				}
				else if ( !Q_stricmpn( token, "FormalName", 10) ) {
					if ( COM_ParseString( &textPtr, &token ) ) {
						continue;
					}

					Q_strncpyz( rankNames[i].formalName, token, sizeof( rankNames[i].formalName ) );

					continue;
				}
				//We hit the end of the cell.
				else if ( !Q_stricmpn( token, "}", 1 ) ) {
					break;
				}
			}

			//Error check.  If we didn't get both a formal and console name, pwn the caller. ;P
			if ( !rankNames[i].consoleName[0] || !rankNames[i].formalName[0] ) {
				Com_Printf( S_COLOR_RED "One or more rank names were not found in rank#: %i\n", i );
				return qfalse;
			}
			else {
				i++;
			}
		}
	}
	return qtrue;
}
Пример #10
0
qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber, qboolean setColors ) 
{
	const char	*token;
	const char	*value;
	const char	*p;
	float	f;
	int		n;

	if ( !saber ) 
	{
		return qfalse;
	}
	
	//Set defaults so that, if it fails, there's at least something there
	WP_SaberSetDefaults( saber, setColors );

	if ( !SaberName || !SaberName[0] ) 
	{
		return qfalse;
	}

	saber->name = G_NewString( SaberName );
	//try to parse it out
	p = SaberParms;
	COM_BeginParseSession();

	// look for the right saber
	while ( p )
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{
			return qfalse;
		}

		if ( !Q_stricmp( token, SaberName ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}
	if ( !p ) 
	{
		return qfalse;
	}

	if ( G_ParseLiteral( &p, "{" ) ) 
	{
		return qfalse;
	}
		
	// parse the saber info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", SaberName );
			return qfalse;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		//saber fullName
		if ( !Q_stricmp( token, "name" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->fullName = G_NewString( value );
			continue;
		}

		//saber type
		if ( !Q_stricmp( token, "saberType" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			int saberType = GetIDForString( SaberTable, value );
			if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS )
			{
				saber->type = (saberType_t)saberType;
			}
			continue;
		}

		//saber hilt
		if ( !Q_stricmp( token, "saberModel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->model = G_NewString( value );
			continue;
		}

		if ( !Q_stricmp( token, "customSkin" ) )
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->skin = G_NewString( value );
			continue;
		}

		//on sound
		if ( !Q_stricmp( token, "soundOn" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundOn = G_SoundIndex( G_NewString( value ) );
			continue;
		}

		//loop sound
		if ( !Q_stricmp( token, "soundLoop" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundLoop = G_SoundIndex( G_NewString( value ) );
			continue;
		}

		//off sound
		if ( !Q_stricmp( token, "soundOff" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundOff = G_SoundIndex( G_NewString( value ) );
			continue;
		}

		if ( !Q_stricmp( token, "numBlades" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			if ( n < 1 || n >= MAX_BLADES )
			{
				G_Error( "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", SaberName, n, MAX_BLADES );
				continue;
			}
			saber->numBlades = n;
			continue;
		}

		// saberColor
		if ( !Q_stricmpn( token, "saberColor", 10 ) ) 
		{
			if ( !setColors )
			{//don't actually want to set the colors
				//read the color out anyway just to advance the *p pointer
				COM_ParseString( &p, &value );
				continue;
			}
			else
			{
				if (strlen(token)==10)
				{
					n = -1;
				}
				else if (strlen(token)==11)
				{
					n = atoi(&token[10])-1;
					if (n > 7 || n < 1 )
					{
						gi.Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, SaberName );
						//read the color out anyway just to advance the *p pointer
						COM_ParseString( &p, &value );
						continue;
					}
				}
				else
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, SaberName );
					//read the color out anyway just to advance the *p pointer
					COM_ParseString( &p, &value );
					continue;
				}

				if ( COM_ParseString( &p, &value ) )	//read the color
				{
					continue;
				}

				if (n==-1)
				{//NOTE: this fills in the rest of the blades with the same color by default
					saber_colors_t color = TranslateSaberColor( value );
					for ( n = 0; n < MAX_BLADES; n++ )
					{
						saber->blade[n].color = color;
					}
				} else 
				{
					saber->blade[n].color = TranslateSaberColor( value );
				}
				continue;
			}
		}

		//saber length
		if ( !Q_stricmpn( token, "saberLength", 11 ) ) 
		{
			if (strlen(token)==11)
			{
				n = -1;
			}
			else if (strlen(token)==12)
			{
				n = atoi(&token[11])-1;
				if (n > 7 || n < 1 )
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, SaberName );
					continue;
				}
			}
			else
			{
				gi.Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, SaberName );
				continue;
			}

			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			//cap
			if ( f < 4.0f )
			{
				f = 4.0f;
			}

			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same length by default
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].lengthMax = f;
				}
			}
			else
			{
				saber->blade[n].lengthMax = f;
			}
			continue;
		}

		//blade radius
		if ( !Q_stricmpn( token, "saberRadius", 11 ) ) 
		{
			if (strlen(token)==11)
			{
				n = -1;
			}
			else if (strlen(token)==12)
			{
				n = atoi(&token[11])-1;
				if (n > 7 || n < 1 )
				{
					gi.Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, SaberName );
					continue;
				}
			}
			else
			{
				gi.Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, SaberName );
				continue;
			}

			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			//cap
			if ( f < 0.25f )
			{
				f = 0.25f;
			}
			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same length by default
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].radius = f;
				}
			}
			else
			{
				saber->blade[n].radius = f;
			}
			continue;
		}

		//locked saber style
		if ( !Q_stricmp( token, "saberStyle" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->style = TranslateSaberStyle( value );
			continue;
		}

		//maxChain
		if ( !Q_stricmp( token, "maxChain" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->maxChain = n;
			continue;
		}

		//lockable
		if ( !Q_stricmp( token, "lockable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->lockable = ((qboolean)(n!=0));
			continue;
		}

		//throwable
		if ( !Q_stricmp( token, "throwable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->throwable = ((qboolean)(n!=0));
			continue;
		}

		//disarmable
		if ( !Q_stricmp( token, "disarmable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->disarmable = ((qboolean)(n!=0));
			continue;
		}

		//active blocking
		if ( !Q_stricmp( token, "blocking" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->activeBlocking = ((qboolean)(n!=0));
			continue;
		}

		//twoHanded
		if ( !Q_stricmp( token, "twoHanded" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->twoHanded = ((qboolean)(n!=0));
			continue;
		}

		//force power restrictions
		if ( !Q_stricmp( token, "forceRestrict" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			int fp = GetIDForString( FPTable, value );
			if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS )
			{
				saber->forceRestrictions |= (1<<fp);
			}
			continue;
		}

		//lockBonus
		if ( !Q_stricmp( token, "lockBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->lockBonus = n;
			continue;
		}

		//parryBonus
		if ( !Q_stricmp( token, "parryBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->parryBonus = n;
			continue;
		}

		//breakParryBonus
		if ( !Q_stricmp( token, "breakParryBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->breakParryBonus = n;
			continue;
		}

		//disarmBonus
		if ( !Q_stricmp( token, "disarmBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->disarmBonus = n;
			continue;
		}

		//single blade saber style
		if ( !Q_stricmp( token, "singleBladeStyle" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->singleBladeStyle = TranslateSaberStyle( value );
			continue;
		}

		//single blade throwable
		if ( !Q_stricmp( token, "singleBladeThrowable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->singleBladeThrowable = ((qboolean)(n!=0));
			continue;
		}

		//broken replacement saber1 (right hand)
		if ( !Q_stricmp( token, "brokenSaber1" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->brokenSaber1 = G_NewString( value );
			continue;
		}
		
		//broken replacement saber2 (left hand)
		if ( !Q_stricmp( token, "brokenSaber2" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->brokenSaber2 = G_NewString( value );
			continue;
		}

		//spins and does damage on return from saberthrow
		if ( !Q_stricmp( token, "returnDamage" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->returnDamage = ((qboolean)(n!=0));
			continue;
		}

		if ( !Q_stricmp( token, "notInMP" ) ) 
		{//ignore this
			SkipRestOfLine( &p );
			continue;
		}

		gi.Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, SaberName );
		SkipRestOfLine( &p );
	}

	//FIXME: precache the saberModel(s)?

	if ( saber->type == SABER_SITH_SWORD )
	{//precache all the sith sword sounds
		Saber_SithSwordPrecache();
	}

	return qtrue;
}
Пример #11
0
/*
==============
Bot_ScriptParseAllCharacters
==============
*/
void Bot_ScriptParseAllCharacters()
{
	char           *pScript;
	char           *token;
	bot_script_global_data_t *bsd;
	char            params[MAX_TOKEN_CHARS];

	if(!level.scriptEntity)
	{
		return;
	}

	pScript = level.scriptEntity;
	COM_BeginParseSession("Bot_ScriptParse");
	numScriptCharacters = 0;
	memset(botCharacterScriptData, 0, sizeof(botCharacterScriptData));

	while(1)
	{
		token = COM_Parse(&pScript);
		// we are expecting a name here
		if(!token[0])
		{
			// end of script
			break;
		}
		if(token[0] == '{' || token[0] == '}')
		{
			G_Error("Bot_ScriptParse(), Error (line %d): entry identifier expected, '%s' found.\n", 1 + COM_GetCurrentParseLine(),
					token);
		}
		// is this a bot?
		if(Q_stricmp(token, "BOT") != 0)
		{
			// not a bot, skip this whole entry
			SkipRestOfLine(&pScript);
			// skip this section
			SkipBracedSection(&pScript);
			//
			continue;
		}
		// this is the name
		if(numScriptCharacters == MAX_BOT_SCRIPT_CHARACTERS)
		{
			G_Error
				("Bot_ScriptParse(), Error (line %d): MAX_BOT_SCRIPT_CHARACTERS exceeded (%i), too many bot script characters\n",
				 1 + COM_GetCurrentParseLine(), MAX_BOT_SCRIPT_CHARACTERS);
			break;
		}
		bsd = &botCharacterScriptData[numScriptCharacters++];
		bsd->lineNum = 1 + COM_GetCurrentParseLine();
		// read the name
		token = COM_Parse(&pScript);
		// we are expecting a name here
		if(!token[0])
		{
			G_Error("Bot_ScriptParse(), Error (line %d): name expected, end of line found.\n", 1 + COM_GetCurrentParseLine());
		}
		if(token[0] == '{' || token[0] == '}')
		{
			G_Error("Bot_ScriptParse(), Error (line %d): name expected, '%s' found.\n", 1 + COM_GetCurrentParseLine(), token);
		}
		// allocate the name
		bsd->name = G_Alloc(strlen(token) + 1);
		Q_strncpyz(bsd->name, token, strlen(token) + 1);
		// read the params
		memset(params, 0, sizeof(params));
		while((token = COM_ParseExt(&pScript, qfalse)) && token[0])
		{
			if(strlen(params) + strlen(token) >= sizeof(params))
			{
				G_Error("Bot_ScriptParse(), Error (line %d): parameters exceed maximum size\n", 1 + COM_GetCurrentParseLine());
			}
			if(strlen(params) > 0)
			{
				Q_strcat(params, sizeof(params), " ");
			}
			Q_strcat(params, sizeof(params), token);
		}
		// allocate the params
		bsd->params = G_Alloc(strlen(params) + 1);
		Q_strncpyz(bsd->params, params, strlen(params) + 1);
		// allocate memory for this character script
		bsd->data = G_Alloc(sizeof(bot_script_data_t));
		memset(bsd->data, 0, sizeof(bot_script_data_t));
		// now parse the script data for this character
		Bot_ScriptParse(bsd->data, &pScript);
	}
}
Пример #12
0
/**
 * @brief Finds and loads all .shader files, combining them into
 * a single large text block that can be scanned for shader names
 */
int ScanAndLoadShaderFilesR1()
{
	char         **shaderFiles;
	char         *buffers[MAX_SHADER_FILES];
	char         *p;
	int          numShaderFiles, i;
	char         *oldp, *token, *textEnd;
	char         **hashMem;
	int          shaderTextHashTableSizes[MAX_SHADERTEXT_HASH], hash;
	unsigned int size;
	char         filename[MAX_QPATH];
	long         sum = 0, summand;

	Com_Memset(buffers, 0, MAX_SHADER_FILES);
	Com_Memset(shaderTextHashTableSizes, 0, MAX_SHADER_FILES);

	// scan for shader files
	shaderFiles = ri.FS_ListFiles("scripts", ".shader", &numShaderFiles);

	if (!shaderFiles || !numShaderFiles)
	{
		Ren_Print("----- ScanAndLoadShaderFilesR1 (no files)-----\n");
		return 0;
	}

	Ren_Print("----- ScanAndLoadShaderFilesR1 (%i files)-----\n", numShaderFiles);

	if (numShaderFiles >= MAX_SHADER_FILES)
	{
		Ren_Drop("MAX_SHADER_FILES limit is reached!");
	}

	// load and parse shader files
	for (i = 0; i < numShaderFiles; i++)
	{
		Com_sprintf(filename, sizeof(filename), "scripts/%s", shaderFiles[i]);
		COM_BeginParseSession(filename);

		Ren_Developer("...loading '%s'\n", filename);
		summand = ri.FS_ReadFile(filename, (void **)&buffers[i]);

		if (!buffers[i])
		{
			Ren_Drop("Couldn't load %s", filename); // in this case shader file is cought/listed but the file can't be read - drop!
		}

		p = buffers[i];
		while (1)
		{
			token = COM_ParseExt(&p, qtrue);

			if (!*token)
			{
				break;
			}

			// Step over the "table"/"guide" and the name
			if (!Q_stricmp(token, "table") || !Q_stricmp(token, "guide"))
			{
				token = COM_ParseExt2(&p, qtrue);

				if (!*token)
				{
					break;
				}
			}

			oldp = p;

			token = COM_ParseExt2(&p, qtrue);
			if (token[0] != '{' && token[1] != '\0')
			{
				Ren_Warning("WARNING: Bad shader file %s has incorrect syntax near token '%s' line %i\n", filename, token, COM_GetCurrentParseLine());
				ri.FS_FreeFile(buffers[i]);
				buffers[i] = NULL;
				break;
			}

			SkipBracedSection(&oldp);
			p = oldp;
		}

		if (buffers[i])
		{
			sum += summand;
		}
	}

	// build single large buffer
	s_shaderTextR1    = (char *)ri.Hunk_Alloc(sum + numShaderFiles * 2, h_low);
	s_shaderTextR1[0] = '\0';
	textEnd           = s_shaderTextR1;

	// free in reverse order, so the temp files are all dumped
	for (i = numShaderFiles - 1; i >= 0 ; i--)
	{
		if (!buffers[i])
		{
			continue;
		}

		strcat(textEnd, buffers[i]);
		strcat(textEnd, "\n");
		textEnd += strlen(textEnd);
		ri.FS_FreeFile(buffers[i]);
	}

	COM_Compress(s_shaderTextR1);

	// free up memory
	ri.FS_FreeFileList(shaderFiles);

	Com_Memset(shaderTextHashTableSizes, 0, sizeof(shaderTextHashTableSizes));
	size = 0;

	p = s_shaderTextR1;
	// look for shader names
	while (1)
	{
		token = COM_ParseExt(&p, qtrue);
		if (token[0] == 0)
		{
			break;
		}

		// skip shader tables
		if (!Q_stricmp(token, "table"))
		{
			// skip table name
			(void) COM_ParseExt2(&p, qtrue);

			SkipBracedSection(&p);
		}
		// support shader templates
		else if (!Q_stricmp(token, "guide"))
		{
			// parse shader name
			token = COM_ParseExt2(&p, qtrue);
			//Ren_Print("...guided '%s'\n", token);

			hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
			shaderTextHashTableSizes[hash]++;
			size++;

			// skip guide name
			token = COM_ParseExt2(&p, qtrue);

			// skip parameters
			token = COM_ParseExt2(&p, qtrue);
			if (Q_stricmp(token, "("))
			{
				Ren_Warning("expected ( found '%s'\n", token);
				break;
			}

			while (1)
			{
				token = COM_ParseExt2(&p, qtrue);

				if (!token[0])
				{
					break;
				}

				if (!Q_stricmp(token, ")"))
				{
					break;
				}
			}

			if (Q_stricmp(token, ")"))
			{
				Ren_Warning("expected ( found '%s'\n", token);
				break;
			}
		}
		else
		{
			hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
			shaderTextHashTableSizes[hash]++;
			size++;
			SkipBracedSection(&p);
		}
	}

	//Ren_Print("Shader hash table size %i\n", size);

	size += MAX_SHADERTEXT_HASH;

	hashMem = (char **)ri.Hunk_Alloc(size * sizeof(char *), h_low);

	for (i = 0; i < MAX_SHADERTEXT_HASH; i++)
	{
		shaderTextHashTableR1[i] = hashMem;
		hashMem                 += shaderTextHashTableSizes[i] + 1;
	}

	Com_Memset(shaderTextHashTableSizes, 0, sizeof(shaderTextHashTableSizes));

	p = s_shaderTextR1;

	// look for shader names
	while (1)
	{
		oldp  = p;
		token = COM_ParseExt(&p, qtrue);
		if (token[0] == 0)
		{
			break;
		}

		// parse shader tables
		if (!Q_stricmp(token, "table"))
		{
			int           depth;
			float         values[FUNCTABLE_SIZE];
			int           numValues;
			shaderTable_t *tb;
			qboolean      alreadyCreated;

			Com_Memset(&values, 0, sizeof(values));
			Com_Memset(&table, 0, sizeof(table));

			token = COM_ParseExt2(&p, qtrue);

			Q_strncpyz(table.name, token, sizeof(table.name));

			// check if already created
			alreadyCreated = qfalse;
			hash           = generateHashValue(table.name, MAX_SHADERTABLE_HASH);
			for (tb = shaderTableHashTable[hash]; tb; tb = tb->next)
			{
				if (Q_stricmp(tb->name, table.name) == 0)
				{
					// match found
					alreadyCreated = qtrue;
					break;
				}
			}

			depth     = 0;
			numValues = 0;
			do
			{
				token = COM_ParseExt2(&p, qtrue);

				if (!Q_stricmp(token, "snap"))
				{
					table.snap = qtrue;
				}
				else if (!Q_stricmp(token, "clamp"))
				{
					table.clamp = qtrue;
				}
				else if (token[0] == '{')
				{
					depth++;
				}
				else if (token[0] == '}')
				{
					depth--;
				}
				else if (token[0] == ',')
				{
					continue;
				}
				else
				{
					if (numValues == FUNCTABLE_SIZE)
					{
						Ren_Warning("WARNING: FUNCTABLE_SIZE hit\n");
						break;
					}
					values[numValues++] = atof(token);
				}
			}
			while (depth && p);

			if (!alreadyCreated)
			{
				Ren_Developer("...generating '%s'\n", table.name);
				GeneratePermanentShaderTable(values, numValues);
			}
		}
		// support shader templates
		else if (!Q_stricmp(token, "guide"))
		{
			// parse shader name
			oldp  = p;
			token = COM_ParseExt2(&p, qtrue);

			//Ren_Print("...guided '%s'\n", token);

			hash                                                          = generateHashValue(token, MAX_SHADERTEXT_HASH);
			shaderTextHashTableR1[hash][shaderTextHashTableSizes[hash]++] = oldp;

			// skip guide name
			token = COM_ParseExt2(&p, qtrue);

			// skip parameters
			token = COM_ParseExt2(&p, qtrue);
			if (Q_stricmp(token, "("))
			{
				Ren_Warning("expected ( found '%s'\n", token);
				break;
			}

			while (1)
			{
				token = COM_ParseExt2(&p, qtrue);

				if (!token[0])
				{
					break;
				}

				if (!Q_stricmp(token, ")"))
				{
					break;
				}
			}

			if (Q_stricmp(token, ")"))
			{
				Ren_Warning("expected ( found '%s'\n", token);
				break;
			}
		}
		else
		{
			hash                                                          = generateHashValue(token, MAX_SHADERTEXT_HASH);
			shaderTextHashTableR1[hash][shaderTextHashTableSizes[hash]++] = oldp;

			SkipBracedSection(&p);
		}
	}

	return numShaderFiles;
}
Пример #13
0
/**
 * @brief Scans the combined text description of all the shader files for
 * the given shader name.
 * @param[in] shaderName
 * @return NULL if not found, otherwise it will return a valid shader
 */
char *FindShaderInShaderTextR1(const char *shaderName)
{
	char *token, *p;
	int  i, hash;

	hash = generateHashValue(shaderName, MAX_SHADERTEXT_HASH);

	for (i = 0; shaderTextHashTableR1[hash][i]; i++)
	{
		p     = shaderTextHashTableR1[hash][i];
		token = COM_ParseExt2(&p, qtrue);
		if (!Q_stricmp(token, shaderName))
		{
			//Ren_Print("found shader '%s' by hashing\n", shaderName);
			return p;
		}
	}

	p = s_shaderTextR1;

	if (!p)
	{
		return NULL;
	}

	// look for label
	while (1)
	{
		token = COM_ParseExt2(&p, qtrue);
		if (token[0] == 0)
		{
			break;
		}

		if (!Q_stricmp(token, shaderName))
		{
			//Ren_Print("found shader '%s' by linear search\n", shaderName);
			return p;
		}
		// skip shader tables
		else if (!Q_stricmp(token, "table"))
		{
			// skip table name
			(void) COM_ParseExt2(&p, qtrue);

			SkipBracedSection(&p);
		}
		// support shader templates
		else if (!Q_stricmp(token, "guide"))
		{
			// parse shader name
			token = COM_ParseExt2(&p, qtrue);

			if (!Q_stricmp(token, shaderName))
			{
				Ren_Print("found shader '%s' by linear search\n", shaderName);
				return p;
			}

			// skip guide name
			token = COM_ParseExt2(&p, qtrue);

			// skip parameters
			token = COM_ParseExt2(&p, qtrue);
			if (Q_stricmp(token, "("))
			{
				break;
			}

			while (1)
			{
				token = COM_ParseExt2(&p, qtrue);

				if (!token[0])
				{
					break;
				}

				if (!Q_stricmp(token, ")"))
				{
					break;
				}
			}

			if (Q_stricmp(token, ")"))
			{
				break;
			}
		}
		else
		{
			// skip the shader body
			SkipBracedSection(&p);
		}
	}

	return NULL;
}
Пример #14
0
qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber ) 
{
	const char	*token;
	const char	*value;
	const char	*p;
	char	useSaber[1024];
	float	f;
	int		n;
	qboolean	triedDefault = qfalse;

	if ( !saber ) 
	{
		return qfalse;
	}
	
	//Set defaults so that, if it fails, there's at least something there
	WP_SaberSetDefaults( saber );

	if ( !SaberName || !SaberName[0] ) 
	{
		strcpy(useSaber, DEFAULT_SABER); //default
		triedDefault = qtrue;
	}
	else
	{
		strcpy(useSaber, SaberName);
	}

	//try to parse it out
	p = SaberParms;
	COM_BeginParseSession("saberinfo");

	// look for the right saber
	while ( p )
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{
			if (!triedDefault)
			{ //fall back to default and restart, should always be there
				p = SaberParms;
				COM_BeginParseSession("saberinfo");
				strcpy(useSaber, DEFAULT_SABER);
				triedDefault = qtrue;
			}
			else
			{
				return qfalse;
			}
		}

		if ( !Q_stricmp( token, useSaber ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}
	if ( !p ) 
	{ //even the default saber isn't found?
		return qfalse;
	}

	//got the name we're using for sure
	strcpy(saber->name, useSaber);

	if ( BG_ParseLiteral( &p, "{" ) ) 
	{
		return qfalse;
	}
		
	// parse the saber info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			Com_Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", useSaber );
			return qfalse;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		//saber fullName
		if ( !Q_stricmp( token, "name" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			strcpy(saber->fullName, value);
			continue;
		}

		//saber type
		if ( !Q_stricmp( token, "saberType" ) ) 
		{
			int saberType;

			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saberType = GetIDForString( SaberTable, value );
			if ( saberType >= SABER_SINGLE && saberType <= NUM_SABERS )
			{
				saber->type = (saberType_t)saberType;
			}
			continue;
		}

		//saber hilt
		if ( !Q_stricmp( token, "saberModel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			strcpy(saber->model, value);
			continue;
		}

		if ( !Q_stricmp( token, "customSkin" ) )
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->skin = trap_R_RegisterSkin(value);
			continue;
		}

		//on sound
		if ( !Q_stricmp( token, "soundOn" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundOn = BG_SoundIndex( (char *)value );
			continue;
		}

		//loop sound
		if ( !Q_stricmp( token, "soundLoop" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundLoop = BG_SoundIndex( (char *)value );
			continue;
		}

		//off sound
		if ( !Q_stricmp( token, "soundOff" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->soundOff = BG_SoundIndex( (char *)value );
			continue;
		}

		if ( !Q_stricmp( token, "numBlades" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			if ( n < 1 || n >= MAX_BLADES )
			{
				Com_Error(ERR_DROP, "WP_SaberParseParms: saber %s has illegal number of blades (%d) max: %d", useSaber, n, MAX_BLADES );
				continue;
			}
			saber->numBlades = n;
			continue;
		}

		// saberColor
		if ( !Q_stricmpn( token, "saberColor", 10 ) ) 
		{
			if (strlen(token)==10)
			{
				n = -1;
			}
			else if (strlen(token)==11)
			{
				n = atoi(&token[10])-1;
				if (n > 7 || n < 1 )
				{
#ifndef FINAL_BUILD
					Com_Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, useSaber );
#endif
					continue;
				}
			}
			else
			{
#ifndef FINAL_BUILD
				Com_Printf( S_COLOR_YELLOW"WARNING: bad saberColor '%s' in %s\n", token, useSaber );
#endif
				continue;
			}

			if ( COM_ParseString( &p, &value ) )	//read the color
			{
				continue;
			}

			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same color by default
				saber_colors_t color = TranslateSaberColor( value );
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].color = color;
				}
			} else 
			{
				saber->blade[n].color = TranslateSaberColor( value );
			}
			continue;
		}

		//saber length
		if ( !Q_stricmpn( token, "saberLength", 11 ) ) 
		{
			if (strlen(token)==11)
			{
				n = -1;
			}
			else if (strlen(token)==12)
			{
				n = atoi(&token[11])-1;
				if (n > 7 || n < 1 )
				{
#ifndef FINAL_BUILD
					Com_Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, useSaber );
#endif
					continue;
				}
			}
			else
			{
#ifndef FINAL_BUILD
				Com_Printf( S_COLOR_YELLOW"WARNING: bad saberLength '%s' in %s\n", token, useSaber );
#endif
				continue;
			}

			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			//cap
			if ( f < 4.0f )
			{
				f = 4.0f;
			}

			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same length by default
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].lengthMax = f;
				}
			}
			else
			{
				saber->blade[n].lengthMax = f;
			}
			continue;
		}

		//blade radius
		if ( !Q_stricmpn( token, "saberRadius", 11 ) ) 
		{
			if (strlen(token)==11)
			{
				n = -1;
			}
			else if (strlen(token)==12)
			{
				n = atoi(&token[11])-1;
				if (n > 7 || n < 1 )
				{
#ifndef FINAL_BUILD
					Com_Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, useSaber );
#endif
					continue;
				}
			}
			else
			{
#ifndef FINAL_BUILD
				Com_Printf( S_COLOR_YELLOW"WARNING: bad saberRadius '%s' in %s\n", token, useSaber );
#endif
				continue;
			}

			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			//cap
			if ( f < 0.25f )
			{
				f = 0.25f;
			}
			if (n==-1)
			{//NOTE: this fills in the rest of the blades with the same length by default
				for ( n = 0; n < MAX_BLADES; n++ )
				{
					saber->blade[n].radius = f;
				}
			}
			else
			{
				saber->blade[n].radius = f;
			}
			continue;
		}

		//locked saber style
		if ( !Q_stricmp( token, "saberStyle" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->style = TranslateSaberStyle( value );
			continue;
		}

		//maxChain
		if ( !Q_stricmp( token, "maxChain" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->maxChain = n;
			continue;
		}

		//lockable
		if ( !Q_stricmp( token, "lockable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->lockable = ((qboolean)(n!=0));
			continue;
		}

		//throwable
		if ( !Q_stricmp( token, "throwable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->throwable = ((qboolean)(n!=0));
			continue;
		}

		//disarmable
		if ( !Q_stricmp( token, "disarmable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->disarmable = ((qboolean)(n!=0));
			continue;
		}

		//active blocking
		if ( !Q_stricmp( token, "blocking" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->activeBlocking = ((qboolean)(n!=0));
			continue;
		}

		//twoHanded
		if ( !Q_stricmp( token, "twoHanded" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->twoHanded = ((qboolean)(n!=0));
			continue;
		}

		//force power restrictions
		if ( !Q_stricmp( token, "forceRestrict" ) ) 
		{
			int fp;

			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			fp = GetIDForString( FPTable, value );
			if ( fp >= FP_FIRST && fp < NUM_FORCE_POWERS )
			{
				saber->forceRestrictions |= (1<<fp);
			}
			continue;
		}

		//lockBonus
		if ( !Q_stricmp( token, "lockBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->lockBonus = n;
			continue;
		}

		//parryBonus
		if ( !Q_stricmp( token, "parryBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->parryBonus = n;
			continue;
		}

		//breakParryBonus
		if ( !Q_stricmp( token, "breakParryBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->breakParryBonus = n;
			continue;
		}

		//disarmBonus
		if ( !Q_stricmp( token, "disarmBonus" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->disarmBonus = n;
			continue;
		}

		//single blade saber style
		if ( !Q_stricmp( token, "singleBladeStyle" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->singleBladeStyle = TranslateSaberStyle( value );
			continue;
		}

		//single blade throwable
		if ( !Q_stricmp( token, "singleBladeThrowable" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->singleBladeThrowable = ((qboolean)(n!=0));
			continue;
		}

		//broken replacement saber1 (right hand)
		if ( !Q_stricmp( token, "brokenSaber1" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			//saber->brokenSaber1 = G_NewString( value );
			continue;
		}
		
		//broken replacement saber2 (left hand)
		if ( !Q_stricmp( token, "brokenSaber2" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			//saber->brokenSaber2 = G_NewString( value );
			continue;
		}

		//spins and does damage on return from saberthrow
		if ( !Q_stricmp( token, "returnDamage" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->returnDamage = ((qboolean)(n!=0));
			continue;
		}

		//stops the saber from drawing marks on the world (good for real-sword type mods)
		if ( !Q_stricmp( token, "noWallMarks" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->noWallMarks = ((qboolean)(n!=0));
			continue;
		}

		//stops the saber from drawing a dynamic light (good for real-sword type mods)
		if ( !Q_stricmp( token, "noDlight" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->noDlight = ((qboolean)(n!=0));
			continue;
		}

		//stops the saber from drawing a blade (good for real-sword type mods)
		if ( !Q_stricmp( token, "noBlade" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->noBlade = ((qboolean)(n!=0));
			continue;
		}

		//default (0) is normal, 1 is a motion blur and 2 is no trail at all (good for real-sword type mods)
		if ( !Q_stricmp( token, "trailStyle" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->trailStyle = n;
			continue;
		}

		//if set, the game will use this shader for marks on enemies instead of the default "gfx/damage/saberglowmark"
		if ( !Q_stricmp( token, "g2MarksShader" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
#ifdef QAGAME//cgame-only cares about this
#elif defined CGAME
			saber->g2MarksShader = trap_R_RegisterShader( value );
#endif
			continue;
		}

		//if non-zero, uses damage done to calculate an appropriate amount of knockback
		if ( !Q_stricmp( token, "knockbackScale" ) ) 
		{
			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->knockbackScale = f;
			continue;
		}

		//scale up or down the damage done by the saber
		if ( !Q_stricmp( token, "damageScale" ) ) 
		{
			if ( COM_ParseFloat( &p, &f ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->damageScale = f;
			continue;
		}

		//if non-zero, the saber never does dismemberment (good for pointed/blunt melee weapons)
		if ( !Q_stricmp( token, "noDismemberment" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->noDismemberment = ((qboolean)(n!=0));
			continue;
		}

		//if non-zero, the saber will not do damage or any effects when it is idle (not in an attack anim).  (good for real-sword type mods)
		if ( !Q_stricmp( token, "noIdleEffect" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->noIdleEffect = ((qboolean)(n!=0));
			continue;
		}

		//spin sound (when thrown)
		if ( !Q_stricmp( token, "spinSound" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->spinSound = BG_SoundIndex( (char *)value );
			continue;
		}

		//swing sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "swingSound1" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->swingSound[0] = BG_SoundIndex( (char *)value );
			continue;
		}

		//swing sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "swingSound2" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->swingSound[1] = BG_SoundIndex( (char *)value );
			continue;
		}

		//swing sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "swingSound3" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->swingSound[2] = BG_SoundIndex( (char *)value );
			continue;
		}

		//hit sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "hitSound1" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->hitSound[0] = BG_SoundIndex( (char *)value );
			continue;
		}

		//hit sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "hitSound2" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->hitSound[1] = BG_SoundIndex( (char *)value );
			continue;
		}

		//hit sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "hitSound3" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->hitSound[2] = BG_SoundIndex( (char *)value );
			continue;
		}

		//block sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "blockSound1" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->blockSound[0] = BG_SoundIndex( (char *)value );
			continue;
		}

		//block sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "blockSound2" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->blockSound[1] = BG_SoundIndex( (char *)value );
			continue;
		}

		//block sound - NOTE: must provide all 3!!!
		if ( !Q_stricmp( token, "blockSound3" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			saber->blockSound[2] = BG_SoundIndex( (char *)value );
			continue;
		}

		//block effect - when saber/sword hits another saber/sword
		if ( !Q_stricmp( token, "blockEffect" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
#ifdef QAGAME//cgame-only cares about this
#elif defined CGAME
			saber->blockEffect = trap_FX_RegisterEffect( (char *)value );
#endif
			continue;
		}

		//hit person effect - when saber/sword hits a person
		if ( !Q_stricmp( token, "hitPersonEffect" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
#ifdef QAGAME//cgame-only cares about this
#elif defined CGAME
			saber->hitPersonEffect = trap_FX_RegisterEffect( (char *)value );
#endif
			continue;
		}

		//hit other effect - when saber/sword hits sopmething else damagable
		if ( !Q_stricmp( token, "hitOtherEffect" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
#ifdef QAGAME//cgame-only cares about this
#elif defined CGAME
			saber->hitOtherEffect = trap_FX_RegisterEffect( (char *)value );
#endif
			continue;
		}

		//if non-zero, the saber will not do the big, white clash flare with other sabers
		if ( !Q_stricmp( token, "noClashFlare" ) ) 
		{
			if ( COM_ParseInt( &p, &n ) ) 
			{
				SkipRestOfLine( &p );
				continue;
			}
			saber->noClashFlare = ((qboolean)(n!=0));
			continue;
		}

		if ( !Q_stricmp( token, "notInMP" ) ) 
		{//ignore this
			SkipRestOfLine( &p );
			continue;
		}
		//FIXME: saber sounds (on, off, loop)

#ifdef _DEBUG
		Com_Printf( "WARNING: unknown keyword '%s' while parsing '%s'\n", token, useSaber );
#endif
		SkipRestOfLine( &p );
	}

	//FIXME: precache the saberModel(s)?

	return qtrue;
}
Пример #15
0
/*
void NPC_Precache ( char *NPCName )

Precaches NPC skins, tgas and md3s.

*/
void NPC_Precache ( gentity_t *spawner )
{
	clientInfo_t	ci={0};
	renderInfo_t	ri={0};
	team_t			playerTeam = TEAM_FREE;
	const char	*token;
	const char	*value;
	const char	*p;
	char	*patch;
	char	sound[MAX_QPATH];
	qboolean	md3Model = qfalse;
	char	playerModel[MAX_QPATH];
	char	customSkin[MAX_QPATH];

	if ( !Q_stricmp( "random", spawner->NPC_type ) )
	{//sorry, can't precache a random just yet
		return;
	}
	strcpy(customSkin,"default");

	p = NPCParms;
	COM_BeginParseSession();

	// look for the right NPC
	while ( p ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{
			return;
		}

		if ( !Q_stricmp( token, spawner->NPC_type ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}

	if ( !p ) 
	{
		return;
	}

	if ( G_ParseLiteral( &p, "{" ) ) 
	{
		return;
	}

	// parse the NPC info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", spawner->NPC_type );
			return;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		// headmodel
		if ( !Q_stricmp( token, "headmodel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}

			if(!Q_stricmp("none", value))
			{
			}
			else
			{
				Q_strncpyz( ri.headModelName, value, sizeof(ri.headModelName), qtrue);
			}
			md3Model = qtrue;
			continue;
		}
		
		// torsomodel
		if ( !Q_stricmp( token, "torsomodel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}

			if(!Q_stricmp("none", value))
			{
			}
			else
			{
				Q_strncpyz( ri.torsoModelName, value, sizeof(ri.torsoModelName), qtrue);
			}
			md3Model = qtrue;
			continue;
		}

		// legsmodel
		if ( !Q_stricmp( token, "legsmodel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			Q_strncpyz( ri.legsModelName, value, sizeof(ri.legsModelName), qtrue);			
			md3Model = qtrue;
			continue;
		}

		// playerModel
		if ( !Q_stricmp( token, "playerModel" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			Q_strncpyz( playerModel, value, sizeof(playerModel), qtrue);			
			md3Model = qfalse;
			continue;
		}

		// customSkin
		if ( !Q_stricmp( token, "customSkin" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			Q_strncpyz( customSkin, value, sizeof(customSkin), qtrue);			
			continue;
		}

		// playerTeam
		if ( !Q_stricmp( token, "playerTeam" ) ) 
		{
			if ( COM_ParseString( &p, &value ) ) 
			{
				continue;
			}
			playerTeam = TranslateTeamName(value);
			continue;
		}

	
		// snd
		if ( !Q_stricmp( token, "snd" ) ) {
			if ( COM_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_BASIC_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customBasicSoundDir = G_NewString( sound );
			}
			continue;
		}

		// sndcombat
		if ( !Q_stricmp( token, "sndcombat" ) ) {
			if ( COM_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_COMBAT_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customCombatSoundDir = G_NewString( sound );
			}
			continue;
		}
		
		// sndextra
		if ( !Q_stricmp( token, "sndextra" ) ) {
			if ( COM_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_EXTRA_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customExtraSoundDir = G_NewString( sound );
			}
			continue;
		}

		// sndjedi
		if ( !Q_stricmp( token, "sndjedi" ) ) {
			if ( COM_ParseString( &p, &value ) ) {
				continue;
			}
			if ( !(spawner->svFlags&SVF_NO_EXTRA_SOUNDS) )
			{
				//FIXME: store this in some sound field or parse in the soundTable like the animTable...
				Q_strncpyz( sound, value, sizeof( sound ) );
				patch = strstr( sound, "/" );
				if ( patch ) 
				{
					*patch = 0;
				}
				ci.customJediSoundDir = G_NewString( sound );
			}
			continue;
		}
	}

	if ( md3Model )
	{
		CG_RegisterClientRenderInfo( &ci, &ri );
	}
	else
	{
		char	skinName[MAX_QPATH];
		//precache ghoul2 model
		gi.G2API_PrecacheGhoul2Model( va( "models/players/%s/model.glm", playerModel ) );
		//precache skin
		Com_sprintf( skinName, sizeof( skinName ), "models/players/%s/model_%s.skin", playerModel, customSkin );
		// lets see if it's out there
		gi.RE_RegisterSkin( skinName );
	}

	//precache this NPC's possible weapons
	NPC_PrecacheWeapons( playerTeam, spawner->spawnflags, spawner->NPC_type );

	CG_RegisterNPCCustomSounds( &ci );
	CG_RegisterNPCEffects( playerTeam );

	//FIXME: Look for a "sounds" directory and precache death, pain, alert sounds
}
Пример #16
0
//void UI_SaberGetHiltInfo( const char *singleHilts[MAX_SABER_HILTS], const char *staffHilts[MAX_SABER_HILTS] )
void UI_SaberGetHiltInfo(void){
	int	numSingleHilts = 0, numStaffHilts = 0;
	const char	*saberName;
	const char	*token;
	const char	*p;

	//go through all the loaded sabers and put the valid ones in the proper list
	p = SaberParms;
	COM_BeginParseSession("saberlist");

	// look for a saber
	while ( p )
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
		{//invalid name
			continue;
		}
		saberName = String_Alloc( token );
		//see if there's a "{" on the next line
		SkipRestOfLine( &p );

		if ( UI_ParseLiteralSilent( &p, "{" ) ) 
		{//nope, not a name, keep looking
			continue;
		}

		//this is a saber name
		if ( !UI_SaberValidForPlayerInMP( saberName ) )
		{
			SkipBracedSection( &p );
			continue;
		}

		if ( UI_IsSaberTwoHanded( saberName ) )
		{
#ifndef DYNAMICMEMORY_SABERS
			if ( numStaffHilts < MAX_SABER_HILTS-1 )//-1 because we have to NULL terminate the list
			{
				staffHilts[numStaffHilts++] = saberName;
			}
			else
			{
				Com_Printf( "WARNING: too many two-handed sabers, ignoring saber '%s'\n", saberName );
			}
#else
			UI_ReaAllocMem((void *)&saberStaffHiltInfo, sizeof(char *), numStaffHilts+1);
			saberStaffHiltInfo[numStaffHilts++] = (char *) saberName;
#endif
		}
		else
		{
#ifndef DYNAMICMEMORY_SABERS
			if ( numSingleHilts < MAX_SABER_HILTS-1 )//-1 because we have to NULL terminate the list
			{
				singleHilts[numSingleHilts++] = saberName;
			}
			else
			{
				Com_Printf( "WARNING: too many one-handed sabers, ignoring saber '%s'\n", saberName );
			}
#else
			UI_ReaAllocMem((void *)&saberSingleHiltInfo, sizeof(char *), numSingleHilts+1);
			saberSingleHiltInfo[numSingleHilts++] = (char *) saberName;
#endif
		}
		//skip the whole braced section and move on to the next entry
		SkipBracedSection( &p );
	}
	//null terminate the list so the UI code knows where to stop listing them
#ifndef DYNAMICMEMORY_SABERS
	singleHilts[numSingleHilts] = NULL;
	staffHilts[numStaffHilts] = NULL;
#else
	saberSingleHiltCount = numSingleHilts;
	saberStaffHiltCount = numStaffHilts;
#endif
}
Пример #17
0
/*
==============
G_Script_ScriptParse

  Parses the script for the given entity
==============
*/
void G_Script_ScriptParse(gentity_t *ent) {
	char                    *pScript;
	qboolean                wantName;
	qboolean                inScript;
	int                     eventNum;
	g_script_event_t        events[G_MAX_SCRIPT_STACK_ITEMS];
	int                     numEventItems;
	g_script_event_t        *curEvent;
	char                    params[MAX_INFO_STRING];
	g_script_stack_action_t *action;
	int                     i;
	int                     bracketLevel;
	qboolean                buildScript;

	if (!ent->scriptName) {
		return;
	}
	if (!level.scriptEntity) {
		return;
	}

	buildScript = trap_Cvar_VariableIntegerValue("com_buildScript");

	pScript  = level.scriptEntity;
	wantName = qtrue;
	inScript = qfalse;
	COM_BeginParseSession("G_Script_ScriptParse");
	bracketLevel  = 0;
	numEventItems = 0;

	memset(events, 0, sizeof (events));

	for (;;) {
		char *token;

		token = COM_Parse(&pScript);

		if (!token[0]) {
			if (!wantName) {
				G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine());
			}
			break;
		}

		// end of script
		if (token[0] == '}') {
			if (inScript) {
				break;
			}
			if (wantName) {
				G_Error("G_Script_ScriptParse(), Error (line %d): '}' found, but not expected.\n", COM_GetCurrentParseLine());
			}
			wantName = qtrue;
		} else if (token[0] == '{') {
			if (wantName) {
				G_Error("G_Script_ScriptParse(), Error (line %d): '{' found, NAME expected.\n", COM_GetCurrentParseLine());
			}
		} else if (wantName) {
			if (!Q_stricmp(token, "bot")) {
				// a bot, skip this whole entry
				SkipRestOfLine(&pScript);
				// skip this section
				SkipBracedSection(&pScript);
				//
				continue;
			}
			if (!Q_stricmp(token, "entity")) {
				// this is an entity, so go back to look for a name
				continue;
			}
			if (!Q_stricmp(ent->scriptName, token)) {
				inScript      = qtrue;
				numEventItems = 0;
			}
			wantName = qfalse;
		} else if (inScript) {
			Q_strlwr(token);
			eventNum = G_Script_EventForString(token);
			if (eventNum < 0) {
				G_Error("G_Script_ScriptParse(), Error (line %d): unknown event: %s.\n", COM_GetCurrentParseLine(), token);
			}

			if (numEventItems >= G_MAX_SCRIPT_STACK_ITEMS) {
				G_Error("G_Script_ScriptParse(), Error (line %d): G_MAX_SCRIPT_STACK_ITEMS reached (%d)\n", COM_GetCurrentParseLine(), G_MAX_SCRIPT_STACK_ITEMS);
			}

			curEvent           = &events[numEventItems];
			curEvent->eventNum = eventNum;
			memset(params, 0, sizeof (params));

			// parse any event params before the start of this event's actions
			while ((token = COM_Parse(&pScript)) != NULL && (token[0] != '{')) {
				if (!token[0]) {
					G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine());
				}

				if (strlen(params)) {      // add a space between each param
					Q_strcat(params, sizeof (params), " ");
				}
				Q_strcat(params, sizeof (params), token);
			}

			if (strlen(params)) {        // copy the params into the event
				curEvent->params = G_Alloc(strlen(params) + 1);
				Q_strncpyz(curEvent->params, params, strlen(params) + 1);
			}

			// parse the actions for this event
			while ((token = COM_Parse(&pScript)) != NULL && (token[0] != '}')) {
				if (!token[0]) {
					G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine());
				}

				action = G_Script_ActionForString(token);
				if (!action) {
					G_Error("G_Script_ScriptParse(), Error (line %d): unknown action: %s.\n", COM_GetCurrentParseLine(), token);
				}

				curEvent->stack.items[curEvent->stack.numItems].action = action;

				memset(params, 0, sizeof (params));

				// Ikkyo - Parse for {}'s if this is a set command
				// Nico, added "create" & "delete" condition
				if (!Q_stricmp(action->actionString, "set") ||
				    !Q_stricmp(action->actionString, "create") ||
				    !Q_stricmp(action->actionString, "delete")) {
					token = COM_Parse(&pScript);
					if (token[0] != '{') {
						COM_ParseError("'{' expected, found: %s.\n", token);
					}

					while ((token = COM_Parse(&pScript)) != NULL && (token[0] != '}')) {
						if (strlen(params)) {     // add a space between each param
							Q_strcat(params, sizeof (params), " ");
						}

						if (strrchr(token, ' ')) {    // need to wrap this param in quotes since it has more than one word
							Q_strcat(params, sizeof (params), "\"");
						}

						Q_strcat(params, sizeof (params), token);

						if (strrchr(token, ' ')) {    // need to wrap this param in quotes since it has mor
							Q_strcat(params, sizeof (params), "\"");
						}
					}
				} else
				// hackly precaching of custom characters
				if (!Q_stricmp(token, "spawnbot")) {
					// this is fairly indepth, so I'll move it to a separate function for readability
					G_Script_ParseSpawnbot(&pScript, params, MAX_INFO_STRING);
				} else {
					token = COM_ParseExt(&pScript, qfalse);
					for (i = 0; token[0]; ++i) {
						if (strlen(params)) {     // add a space between each param
							Q_strcat(params, sizeof (params), " ");
						}

						if (i == 0) {
							// Special case: playsound's need to be cached on startup to prevent in-game pauses
							if (!Q_stricmp(action->actionString, "playsound")) {
								G_SoundIndex(token);
							} else if (!Q_stricmp(action->actionString, "changemodel")) {
								G_ModelIndex(token);
							} else if (buildScript &&
							           (!Q_stricmp(action->actionString, "mu_start") ||
							            !Q_stricmp(action->actionString, "mu_play") ||
							            !Q_stricmp(action->actionString, "mu_queue") ||
							            !Q_stricmp(action->actionString, "startcam")) &&
							           strlen(token)) {
								trap_SendServerCommand(-1, va("addToBuild %s\n", token));
							}
						}

						if ((i == 0 || i == 1) && !Q_stricmp(action->actionString, "remapshader")) {
							G_ShaderIndex(token);
						}

						if (strrchr(token, ' ')) {    // need to wrap this param in quotes since it has more than one word
							Q_strcat(params, sizeof (params), "\"");
						}

						Q_strcat(params, sizeof (params), token);

						if (strrchr(token, ' ')) {    // need to wrap this param in quotes since it has more than one word
							Q_strcat(params, sizeof (params), "\"");
						}

						token = COM_ParseExt(&pScript, qfalse);
					}
				}

				if (strlen(params)) {     // copy the params into the event
					curEvent->stack.items[curEvent->stack.numItems].params = G_Alloc(strlen(params) + 1);
					Q_strncpyz(curEvent->stack.items[curEvent->stack.numItems].params, params, strlen(params) + 1);
				}

				curEvent->stack.numItems++;

				if (curEvent->stack.numItems >= G_MAX_SCRIPT_STACK_ITEMS) {
					G_Error("G_Script_ScriptParse(): script exceeded G_MAX_SCRIPT_STACK_ITEMS (%d), line %d\n", G_MAX_SCRIPT_STACK_ITEMS, COM_GetCurrentParseLine());
				}
			}

			numEventItems++;
		} else {   // skip this character completely
			// TTimo gcc: suggest parentheses around assignment used as truth value
			while ((token = COM_Parse(&pScript)) != NULL) {
				if (!token[0]) {
					G_Error("G_Script_ScriptParse(), Error (line %d): '}' expected, end of script found.\n", COM_GetCurrentParseLine());
				} else if (token[0] == '{') {
					bracketLevel++;
				} else if (token[0] == '}' && !--bracketLevel) {
					break;
				}
			}
		}
	}

	// alloc and copy the events into the gentity_t for this cast
	if (numEventItems > 0) {
		ent->scriptEvents = G_Alloc(sizeof (g_script_event_t) * numEventItems);
		memcpy(ent->scriptEvents, events, sizeof (g_script_event_t) * numEventItems);
		ent->numScriptEvents = numEventItems;
	}
}
Пример #18
0
void NPC_PrecacheAnimationCFG( const char *NPC_type )
{
	char	*token;
	char	*value;
	char	*p;
	int		junk;

	if ( !Q_stricmp( "random", NPC_type ) )
	{//sorry, can't precache a random just yet
		return;
	}

	p = NPCParms;
	COM_BeginParseSession();

	// look for the right NPC
	while ( p ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( token[0] == 0 )
			return;

		if ( !Q_stricmp( token, NPC_type ) ) 
		{
			break;
		}

		SkipBracedSection( &p );
	}

	if ( !p ) 
	{
		return;
	}

	if ( G_ParseLiteral( &p, "{" ) ) 
	{
		return;
	}

	// parse the NPC info block
	while ( 1 ) 
	{
		token = COM_ParseExt( &p, qtrue );
		if ( !token[0] ) 
		{
			gi.Printf( S_COLOR_RED"ERROR: unexpected EOF while parsing '%s'\n", NPC_type );
			return;
		}

		if ( !Q_stricmp( token, "}" ) ) 
		{
			break;
		}

		// legsmodel
		if ( !Q_stricmp( token, "legsmodel" ) ) 
		{
			if ( G_ParseString( &p, &value ) ) 
			{
				continue;
			}
			G_ParseAnimFileSet( value, &junk, qfalse );
			return;
		}
	}
}