Exemplo n.º 1
0
static void CG_ConfigStringModified( void ) {
	const char	*str;
	int		num;

	num = atoi( CG_Argv( 1 ) );

	// get the gamestate from the client system, which will have the
	// new configstring already integrated
	cgi_GetGameState( &cgs.gameState );

	// look up the individual string that was modified
	str = CG_ConfigString( num );

	// do something with it if necessary
	if ( num == CS_ITEMS ) {
		int i;
		for ( i = 1 ; i < bg_numItems ; i++ ) {
			if ( str[ i ] == '1' ) 
			{
				if (bg_itemlist[i].classname)
				{
					CG_RegisterItemSounds( i );
					CG_RegisterItemVisuals( i );
				}
			}
		}
	}
	else if ( num == CS_MUSIC ) {
		CG_StartMusic( qtrue );
	} else if ( num == CS_SERVERINFO ) {
		CG_ParseServerinfo();
	} else if ( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) {
		cgs.model_draw[ num-CS_MODELS ] = cgi_R_RegisterModel( str );
//		OutputDebugString(va("### CG_ConfigStringModified(): cgs.model_draw[%d] = \"%s\"\n",num-CS_MODELS,str));
// GHOUL2 Insert start
	} else if ( num >= CS_CHARSKINS && num < CS_CHARSKINS+MAX_CHARSKINS ) {
		cgs.skins[ num-CS_CHARSKINS ] = cgi_R_RegisterSkin( str );
// Ghoul2 Insert end
	} else if ( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_SOUNDS ) {
		if ( str[0] != '*' ) {
			cgs.sound_precache[ num-CS_SOUNDS] = cgi_S_RegisterSound( str );
		}
	} 
	else if ( num >= CS_EFFECTS && num < CS_EFFECTS + MAX_FX ) 
	{
		theFxScheduler.RegisterEffect( str );
	} 
	else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) {
		CG_NewClientinfo( num - CS_PLAYERS );
		CG_RegisterClientModels( num - CS_PLAYERS );
	}
	else if ( num >= CS_LIGHT_STYLES && num < CS_LIGHT_STYLES + (MAX_LIGHT_STYLES*3))
	{
		CG_SetLightstyle(num - CS_LIGHT_STYLES);
	}
	else if ( num >= CS_WORLD_FX && num < CS_WORLD_FX + MAX_WORLD_FX )
	{
		cgi_R_WorldEffectCommand( str );
	}
}
static void CG_ConfigStringModified( void ) {
	const char	*str;
	int		num;

	num = atoi( CG_Argv( 1 ) );

	// get the gamestate from the client system, which will have the
	// new configstring already integrated
	cgi_GetGameState( &cgs.gameState );

	// look up the individual string that was modified
	str = CG_ConfigString( num );

	// do something with it if necessary
	if ( num == CS_MUSIC ) {
		CG_StartMusic();
	} else if ( num == CS_SERVERINFO ) {
		CG_ParseServerinfo();
	} else if ( num >= CS_MODELS && num < CS_MODELS+MAX_MODELS ) {
		cgs.model_draw[ num-CS_MODELS ] = cgi_R_RegisterModel( str );
	} else if ( num >= CS_SOUNDS && num < CS_SOUNDS+MAX_MODELS ) {
		if ( str[0] != '*' ) {
			cgs.sound_precache[ num-CS_SOUNDS] = cgi_S_RegisterSound( str );
		}
	} 
	else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) {
		CG_NewClientinfo( num - CS_PLAYERS );
		CG_RegisterClientModels( num - CS_PLAYERS );
	}
}
Exemplo n.º 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;
}