Пример #1
0
/*
====================
G_ParseSpawnVars

Parses a brace bounded set of key / value pairs out of the
level's entity strings into level.spawnVars[]

This does not actually spawn an entity.
====================
*/
bool G_ParseSpawnVars( bool inSubBSP ) 
{
	char	keyname[MAX_TOKEN_CHARS];
	char	com_token[MAX_TOKEN_CHARS];

	level.numSpawnVars = 0;
	level.numSpawnVarChars = 0;

	// parse the opening brace
	if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) 
	{
		// end of spawn string
		return false;
	}
	
	if ( com_token[0] != '{' ) 
	{
		Com_Error( ERR_FATAL, "G_ParseSpawnVars: found %s when expecting {",com_token );
	}

	// go through all the key / value pairs
	while ( 1 ) 
	{
		// parse key
		if ( !trap_GetEntityToken( keyname, sizeof( keyname ) ) ) 
		{
			Com_Error( ERR_FATAL, "G_ParseSpawnVars: EOF without closing brace" );
		}

		if ( keyname[0] == '}' ) 
		{
			break;
		}
		
		// parse value	
		if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) 
		{
			Com_Error( ERR_FATAL, "G_ParseSpawnVars: EOF without closing brace" );
		}

		if ( com_token[0] == '}' ) 
		{
			Com_Error( ERR_FATAL, "G_ParseSpawnVars: closing brace without data" );
		}
		
		if ( level.numSpawnVars == MAX_SPAWN_VARS ) 
		{
			Com_Error( ERR_FATAL, "G_ParseSpawnVars: MAX_SPAWN_VARS" );
		}
		
		AddSpawnField(keyname, com_token);
	}

	if (inSubBSP)
	{
		HandleEntityAdjustment();
	}

	return true;
}
Пример #2
0
static void HandleEntityAdjustment( void ) {
	char		*value;
	vector3		origin, newOrigin, angles;
	char		temp[MAX_QPATH];
	float		rotation;

	G_SpawnString( "origin", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		sscanf( value, "%f %f %f", &origin.x, &origin.y, &origin.z );
	}
	else {
		origin.x = origin.y = origin.z = 0.0f;
	}

	rotation = DEG2RAD( level.mRotationAdjust );
	newOrigin.x = origin.x*cosf( rotation ) - origin.y*sinf( rotation );
	newOrigin.y = origin.x*sinf( rotation ) + origin.y*cosf( rotation );
	newOrigin.z = origin.z;
	VectorAdd( &newOrigin, &level.mOriginAdjust, &newOrigin );
	// damn VMs don't handle outputing a float that is compatible with sscanf in all cases
	Com_sprintf( temp, MAX_QPATH, "%0.0f %0.0f %0.0f", newOrigin.x, newOrigin.y, newOrigin.z );
	AddSpawnField( "origin", temp );

	G_SpawnString( "angles", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		sscanf( value, "%f %f %f", &angles.x, &angles.y, &angles.z );

		angles.yaw = fmod( angles.y + level.mRotationAdjust, 360.0f );
		// damn VMs don't handle outputing a float that is compatible with sscanf in all cases
		Com_sprintf( temp, MAX_QPATH, "%0.0f %0.0f %0.0f", angles.x, angles.y, angles.z );
		AddSpawnField( "angles", temp );
	}
	else {
		G_SpawnString( "angle", NOVALUE, &value );
		if ( Q_stricmp( value, NOVALUE ) != 0 ) {
			sscanf( value, "%f", &angles.y );
		}
		else {
			angles.y = 0.0f;
		}
		angles.y = fmod( angles.y + level.mRotationAdjust, 360.0f );
		Com_sprintf( temp, MAX_QPATH, "%0.0f", angles.y );
		AddSpawnField( "angle", temp );
	}

	// RJR experimental code for handling "direction" field of breakable brushes
	// though direction is rarely ever used.
	G_SpawnString( "direction", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		sscanf( value, "%f %f %f", &angles.x, &angles.y, &angles.z );
	}
	else {
		angles.x = angles.y = angles.z = 0.0f;
	}
	angles.y = fmod( angles.y + level.mRotationAdjust, 360.0f );
	Com_sprintf( temp, MAX_QPATH, "%0.0f %0.0f %0.0f", angles.x, angles.y, angles.z );
	AddSpawnField( "direction", temp );


	AddSpawnField( "BSPInstanceID", level.mTargetAdjust );

	G_SpawnString( "targetname", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "targetname", temp );
	}

	G_SpawnString( "target", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "target", temp );
	}

	G_SpawnString( "killtarget", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "killtarget", temp );
	}

	G_SpawnString( "brushparent", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "brushparent", temp );
	}

	G_SpawnString( "brushchild", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "brushchild", temp );
	}

	G_SpawnString( "enemy", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "enemy", temp );
	}

	G_SpawnString( "ICARUSname", NOVALUE, &value );
	if ( Q_stricmp( value, NOVALUE ) != 0 ) {
		Com_sprintf( temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value );
		AddSpawnField( "ICARUSname", temp );
	}
}
Пример #3
0
static void HandleEntityAdjustment(void)
{
	char		*value;
	vec3_t		origin, newOrigin, angles;
	char		temp[MAX_QPATH];
	float		rotation;

	G_SpawnString("origin", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sscanf( value, "%f %f %f", &origin[0], &origin[1], &origin[2] );
	}
	else
	{
		origin[0] = origin[1] = origin[2] = 0.0;
	}

	rotation = DEG2RAD(level.mRotationAdjust);
	newOrigin[0] = origin[0]*cos(rotation) - origin[1]*sin(rotation);
	newOrigin[1] = origin[0]*sin(rotation) + origin[1]*cos(rotation);
	newOrigin[2] = origin[2];
	VectorAdd(newOrigin, level.mOriginAdjust, newOrigin);
	// damn VMs don't handle outputing a float that is compatible with sscanf in all cases
	sprintf_s(temp, MAX_QPATH, "%0.0f %0.0f %0.0f", newOrigin[0], newOrigin[1], newOrigin[2]);
	AddSpawnField("origin", temp);

	G_SpawnString("angles", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sscanf( value, "%f %f %f", &angles[0], &angles[1], &angles[2] );

		angles[1] = fmod(angles[1] + level.mRotationAdjust, 360.0);
		// damn VMs don't handle outputing a float that is compatible with sscanf in all cases
		sprintf_s(temp, MAX_QPATH, "%0.0f %0.0f %0.0f", angles[0], angles[1], angles[2]);
		AddSpawnField("angles", temp);
	}
	else
	{
		G_SpawnString("angle", NOVALUE, &value);
		if (strcmp(value, NOVALUE) != 0)
		{
			sscanf( value, "%f", &angles[1] );
		}
		else
		{
			angles[1] = 0.0;
		}
		angles[1] = fmod(angles[1] + level.mRotationAdjust, 360.0);
		sprintf_s(temp, MAX_QPATH, "%0.0f", angles[1]);
		AddSpawnField("angle", temp);
	}

	// RJR experimental code for handling "direction" field of breakable brushes
	// though direction is rarely ever used.
	G_SpawnString("direction", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sscanf( value, "%f %f %f", &angles[0], &angles[1], &angles[2] );
	}
	else
	{
		angles[0] = angles[1] = angles[2] = 0.0;
	}
	angles[1] = fmod(angles[1] + level.mRotationAdjust, 360.0);
	sprintf_s(temp, MAX_QPATH, "%0.0f %0.0f %0.0f", angles[0], angles[1], angles[2]);
	AddSpawnField("direction", temp);


	AddSpawnField("BSPInstanceID", level.mTargetAdjust);

	G_SpawnString("targetname", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("targetname", temp);
	}

	G_SpawnString("target", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("target", temp);
	}

	G_SpawnString("killtarget", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("killtarget", temp);
	}

	G_SpawnString("brushparent", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("brushparent", temp);
	}

	G_SpawnString("brushchild", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("brushchild", temp);
	}

	G_SpawnString("enemy", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("enemy", temp);
	}

	G_SpawnString("ICARUSname", NOVALUE, &value);
	if (strcmp(value, NOVALUE) != 0)
	{
		sprintf_s(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
		AddSpawnField("ICARUSname", temp);
	}
}
Пример #4
0
// For Maker Mod objects
// combine the two sets of spawnVars. newVars overwrite spawnVars
// we end up with level.spawnVars setup with our final values, the values applied to our ent, 
// and the appropriate spawn function executed.
void G_ApplySpawnVars( gentity_t *ent, char *spawnVars, char *newVars ) {
	int			i;
	char		*token;
	//static char *gametypeNames[] = {"ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty"};
	char* p;
	char field[MAX_FIELDNAME_LENGTH + 1];

	level.numSpawnVars = 0;
	level.numSpawnVarChars = 0;
	level.spawnVarChars[0] = '/0';

	p = spawnVars;

	while ( p )
	{
		token = ParseExt( &p, qfalse );  // TODO : make sure it's safe to use this function
		if ( token[0] == 0 )
			break;

		strncpy( field, token, MAX_FIELDNAME_LENGTH  );

		token = ParseExt( &p, qfalse );
		if ( token[0] == 0 )
			break;

		AddSpawnField( field, token );
	}

	p = newVars;

	while ( p )
	{
		token = ParseExt( &p, qfalse );  // TODO : make sure it's safe to use this function
		if ( token[0] == 0 )
			break;

		strncpy( field, token, MAX_FIELDNAME_LENGTH  );

		token = ParseExt( &p, qfalse );
		if ( token[0] == 0 )
			break;

		AddSpawnField( field, token );
	}

	for ( i = 0 ; i < level.numSpawnVars ; i++ ) {
		BG_ParseField( fields, level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent );
	}

	// move editor origin to pos
	VectorCopy( ent->s.origin, ent->s.pos.trBase );
	VectorCopy( ent->s.origin, ent->r.currentOrigin );


	// if we didn't get a classname, don't bother spawning anything
	if ( !G_CallSpawn( ent ) ) {
		//G_FreeEntity( ent );
	}

	//Tag on the ICARUS scripting information only to valid recipients
	if ( trap_ICARUS_ValidEnt( ent ) )
	{
		trap_ICARUS_InitEnt( ent );

		if ( ent->classname && ent->classname[0] )
		{
			if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 )
			{//Not an NPC_spawner (rww - probably don't even care for MP, but whatever)
				G_ActivateBehavior( ent, BSET_SPAWN );
			}
		}
	}
}