Exemple #1
0
//------------------------------------------------------
// ParseGroupFlags
//	Group flags are generic in nature, so we can easily
//	use a generic function to parse them in, then the
//	caller can shift them into the appropriate range.
//
// input:
//	string that contains the flag strings
//  *flags returns the set bit flags
//
// return:
//	success of parse operation.
//------------------------------------------------------
bool CPrimitiveTemplate::ParseGroupFlags( const gsl::cstring_view& val, int& flags )
{
	// For a sub group, really you probably only have one or two flags set
	std::array< gsl::cstring_view, 4 > flag;

	const auto availableFlag = scanStrings( val, flag );

	// Clear out the flags field, then convert the flag string to an actual value ( use generic flags )
	flags = 0;

	bool ok = true;
	for( auto& cur : availableFlag  )
	{
		static StringViewIMap< int > flagNames{
			{ CSTRING_VIEW( "linear" ), FX_LINEAR },
			{ CSTRING_VIEW( "nonlinear" ), FX_NONLINEAR },
			{ CSTRING_VIEW( "wave" ), FX_WAVE },
			{ CSTRING_VIEW( "random" ), FX_RAND },
			{ CSTRING_VIEW( "clamp" ), FX_CLAMP },
		};

		auto pos = flagNames.find( cur );
		if( pos == flagNames.end() )
		{
			ok = false;
		}
		else
		{
			flags |= pos->second;
		}
	}

	return ok;
}
Exemple #2
0
//------------------------------------------------------
// ParseLength
//	Takes a length group and chomps out any pairs contained
//	in it.
//
// input:
//	the parse group to process
//
// return:
//	success of parse operation.
//------------------------------------------------------
bool CPrimitiveTemplate::ParseLength( const CGPGroup& grp )
{
	static StringViewIMap< ParseMethod > parseMethods{
		{ CSTRING_VIEW( "start" ), &CPrimitiveTemplate::ParseLengthStart },

		{ CSTRING_VIEW( "end" ), &CPrimitiveTemplate::ParseLengthEnd },

		{ CSTRING_VIEW( "parm" ), &CPrimitiveTemplate::ParseLengthParm },
		{ CSTRING_VIEW( "parms" ), &CPrimitiveTemplate::ParseLengthParm },

		{ CSTRING_VIEW( "flag" ), &CPrimitiveTemplate::ParseLengthFlags },
		{ CSTRING_VIEW( "flags" ), &CPrimitiveTemplate::ParseLengthFlags },
	};
	return ParseGroup( grp, parseMethods, "Length" );
}
Exemple #3
0
bool CGPGroup::Parse( gsl::cstring_view& data, const bool topLevel )
{
	while( true )
	{
		gsl::cstring_view token = GetToken( data, true );

		if( token.empty() )
		{
			if ( topLevel )
			{
				// top level parse; there was no opening "{", so there should be no closing one either.
				return true;
			}
			else
			{
				// end of data - error!
				return false;
			}
		}
		else if( token == CSTRING_VIEW( "}" ) )
		{
			if( topLevel )
			{
				// top-level group; there was no opening "{" so there should be no closing one, either.
				return false;
			}
			else
			{
				// ending brace for this group
				return true;
			}
		}
		gsl::cstring_view lastToken = token;

		// read ahead to see what we are doing
		token = GetToken( data, true, true );
		if( token == CSTRING_VIEW( "{" ) )
		{
			// new sub group
			mSubGroups.emplace_back( lastToken );
			if( !mSubGroups.back().Parse( data, false ) )
			{
				return false;
			}
		}
		else if( token == CSTRING_VIEW( "[" ) )
		{
			// new list
			mProperties.emplace_back( lastToken );
			CGPProperty& list = mProperties.back();
			while( true )
			{
				token = GetToken( data, true, true );
				if( token.empty() )
				{
					return false;
				}
				if( token == CSTRING_VIEW( "]" ) )
				{
					break;
				}
				list.AddValue( token );
			}
		}
		else
		{
			// new value
			mProperties.emplace_back( lastToken, token );
		}
	}
}
Exemple #4
0
//------------------------------------------------------
// ParseSpawnFlags
//	These kinds of flags control how things spawn.  They
//	never get passed on to a primitive.
//
// input:
//	string that contains the flag strings
//
// return:
//	success of parse operation.
//------------------------------------------------------
bool CPrimitiveTemplate::ParseSpawnFlags( const gsl::cstring_view& val )
{
	std::array< gsl::cstring_view, 7 > flag;

	// For a primitive, really you probably only have two or less flags set
	const auto availableFlag = scanStrings( val, flag );

	bool ok = true;
	for( auto& cur : availableFlag )
	{
		static StringViewIMap< int > flagNames{
			{ CSTRING_VIEW( "org2fromTrace" ), FX_ORG2_FROM_TRACE },
			{ CSTRING_VIEW( "traceImpactFx" ), FX_TRACE_IMPACT_FX },
			{ CSTRING_VIEW( "org2isOffset" ), FX_ORG2_IS_OFFSET },
			{ CSTRING_VIEW( "cheapOrgCalc" ), FX_CHEAP_ORG_CALC },
			{ CSTRING_VIEW( "cheapOrg2Calc" ), FX_CHEAP_ORG2_CALC },
			{ CSTRING_VIEW( "absoluteVel" ), FX_VEL_IS_ABSOLUTE },
			{ CSTRING_VIEW( "absoluteAccel" ), FX_ACCEL_IS_ABSOLUTE },
			{ CSTRING_VIEW( "orgOnSphere" ), FX_ORG_ON_SPHERE },
			{ CSTRING_VIEW( "orgOnCylinder" ), FX_ORG_ON_CYLINDER },
			{ CSTRING_VIEW( "axisFromSphere" ), FX_AXIS_FROM_SPHERE },
			{ CSTRING_VIEW( "randrotaroundfwd" ), FX_RAND_ROT_AROUND_FWD },
			{ CSTRING_VIEW( "evenDistribution" ), FX_EVEN_DISTRIBUTION },
			{ CSTRING_VIEW( "rgbComponentInterpolation" ), FX_RGB_COMPONENT_INTERP },
			{ CSTRING_VIEW( "lessAttenuation" ), FX_SND_LESS_ATTENUATION },
		};
		auto pos = flagNames.find( cur );
		if( pos == flagNames.end() )
		{
			ok = false;
		}
		else
		{
			mSpawnFlags |= pos->second;
		}
	}

	return ok;
}
Exemple #5
0
//------------------------------------------------------
// ParseFlags
//	These are flags that are not specific to a group,
//	rather, they are specific to the whole primitive.
//
// input:
//	string that contains the flag strings
//
// return:
//	success of parse operation.
//------------------------------------------------------
bool CPrimitiveTemplate::ParseFlags( const gsl::cstring_view& val )
{
	// For a primitive, really you probably only have two or less flags set
	std::array< gsl::cstring_view, 7 > flag;

	const auto availableFlag = scanStrings( val, flag );

	bool	ok = true;
	for( auto& cur : availableFlag )
	{
		static StringViewIMap< int > flagNames{
			{ CSTRING_VIEW( "useModel" ), FX_ATTACHED_MODEL },
			{ CSTRING_VIEW( "useBBox" ), FX_USE_BBOX },
			{ CSTRING_VIEW( "usePhysics" ), FX_APPLY_PHYSICS },
			{ CSTRING_VIEW( "expensivePhysics" ), FX_EXPENSIVE_PHYSICS },
			//rww - begin g2 stuff
			{ CSTRING_VIEW( "ghoul2Collision" ), ( FX_GHOUL2_TRACE | FX_APPLY_PHYSICS | FX_EXPENSIVE_PHYSICS ) },
			{ CSTRING_VIEW( "ghoul2Decals" ), FX_GHOUL2_DECALS },
			//rww - end
			{ CSTRING_VIEW( "impactKills" ), FX_KILL_ON_IMPACT },
			{ CSTRING_VIEW( "impactFx" ), FX_IMPACT_RUNS_FX },
			{ CSTRING_VIEW( "deathFx" ), FX_DEATH_RUNS_FX },
			{ CSTRING_VIEW( "useAlpha" ), FX_CLAMP },
			{ CSTRING_VIEW( "emitFx" ), FX_EMIT_FX },
			{ CSTRING_VIEW( "depthHack" ), FX_DEPTH_HACK },
			{ CSTRING_VIEW( "setShaderTime" ), FX_SET_SHADER_TIME },
		};

		auto pos = flagNames.find( cur );
		if( pos == flagNames.end() )
		{ // we have badness going on, but continue on in case there are any valid fields in here
			ok = false;
		}
		else
		{
			mFlags |= pos->second;
		}
	}

	return ok;
}
Exemple #6
0
// Parse a primitive, apply defaults first, grab any base level
//	key pairs, then process any sub groups we may contain.
//------------------------------------------------------
bool CPrimitiveTemplate::ParsePrimitive( const CGPGroup& grp )
{
	// Property
	for( auto& prop : grp.GetProperties() )
	{
		// Single Value Parsing
		{
			static StringViewIMap< ParseMethod > parseMethods{
				{ CSTRING_VIEW( "count" ), &CPrimitiveTemplate::ParseCount },
				{ CSTRING_VIEW( "life" ), &CPrimitiveTemplate::ParseLife },
				{ CSTRING_VIEW( "delay" ), &CPrimitiveTemplate::ParseDelay },
				{ CSTRING_VIEW( "bounce" ), &CPrimitiveTemplate::ParseElasticity },
				{ CSTRING_VIEW( "intensity" ), &CPrimitiveTemplate::ParseElasticity },
				{ CSTRING_VIEW( "min" ), &CPrimitiveTemplate::ParseMin },
				{ CSTRING_VIEW( "max" ), &CPrimitiveTemplate::ParseMax },
				{ CSTRING_VIEW( "angle" ), &CPrimitiveTemplate::ParseAngle },
				{ CSTRING_VIEW( "angles" ), &CPrimitiveTemplate::ParseAngle },
				{ CSTRING_VIEW( "angleDelta" ), &CPrimitiveTemplate::ParseAngleDelta },
				{ CSTRING_VIEW( "velocity" ), &CPrimitiveTemplate::ParseVelocity },
				{ CSTRING_VIEW( "vel" ), &CPrimitiveTemplate::ParseVelocity },
				{ CSTRING_VIEW( "acceleration" ), &CPrimitiveTemplate::ParseAcceleration },
				{ CSTRING_VIEW( "accel" ), &CPrimitiveTemplate::ParseAcceleration },
				{ CSTRING_VIEW( "gravity" ), &CPrimitiveTemplate::ParseGravity },
				{ CSTRING_VIEW( "density" ), &CPrimitiveTemplate::ParseDensity },
				{ CSTRING_VIEW( "variance" ), &CPrimitiveTemplate::ParseVariance },
				{ CSTRING_VIEW( "origin" ), &CPrimitiveTemplate::ParseOrigin1 },
				{ CSTRING_VIEW( "origin2" ), &CPrimitiveTemplate::ParseOrigin2 },
				{ CSTRING_VIEW( "radius" ), &CPrimitiveTemplate::ParseRadius },
				{ CSTRING_VIEW( "height" ), &CPrimitiveTemplate::ParseHeight },
				{ CSTRING_VIEW( "wind" ), &CPrimitiveTemplate::ParseWindModifier },
				{ CSTRING_VIEW( "rotation" ), &CPrimitiveTemplate::ParseRotation },
				{ CSTRING_VIEW( "rotationDelta" ), &CPrimitiveTemplate::ParseRotationDelta },
				{ CSTRING_VIEW( "flags" ), &CPrimitiveTemplate::ParseFlags },
				{ CSTRING_VIEW( "flag" ), &CPrimitiveTemplate::ParseFlags },
				{ CSTRING_VIEW( "spawnFlags" ), &CPrimitiveTemplate::ParseSpawnFlags },
				{ CSTRING_VIEW( "spawnFlag" ), &CPrimitiveTemplate::ParseSpawnFlags },
			};
			auto pos = parseMethods.find( prop.GetName() );
			if( pos != parseMethods.end() )
			{
				ParseMethod method = pos->second;
				( this->*method )( prop.GetTopValue() );
				continue;
			}
		}
		// Property Parsing
		{
			using PropertyParseMethod = bool( CPrimitiveTemplate::* )( const CGPProperty& );
			static StringViewIMap< PropertyParseMethod > parseMethods{
				{ CSTRING_VIEW( "shaders" ), &CPrimitiveTemplate::ParseShaders },
				{ CSTRING_VIEW( "shader" ), &CPrimitiveTemplate::ParseShaders },
				{ CSTRING_VIEW( "models" ), &CPrimitiveTemplate::ParseModels },
				{ CSTRING_VIEW( "model" ), &CPrimitiveTemplate::ParseModels },
				{ CSTRING_VIEW( "sounds" ), &CPrimitiveTemplate::ParseSounds },
				{ CSTRING_VIEW( "sound" ), &CPrimitiveTemplate::ParseSounds },
				{ CSTRING_VIEW( "impactfx" ), &CPrimitiveTemplate::ParseImpactFxStrings },
				{ CSTRING_VIEW( "deathfx" ), &CPrimitiveTemplate::ParseDeathFxStrings },
				{ CSTRING_VIEW( "emitfx" ), &CPrimitiveTemplate::ParseEmitterFxStrings },
				{ CSTRING_VIEW( "playfx" ), &CPrimitiveTemplate::ParsePlayFxStrings },
			};
			auto pos = parseMethods.find( prop.GetName() );
			if( pos != parseMethods.end() )
			{
				PropertyParseMethod method = pos->second;
				( this->*method )( prop );
				continue;
			}
		}
		// Special Cases
		if( Q::stricmp( prop.GetName(), CSTRING_VIEW( "cullrange" ) ) == Q::Ordering::EQ )
		{
			mCullRange = Q::svtoi( prop.GetTopValue() );
			mCullRange *= mCullRange; // Square
		}
		else if( Q::stricmp( prop.GetName(), CSTRING_VIEW( "name" ) ) == Q::Ordering::EQ )
		{
			if( !prop.GetTopValue().empty() )
			{
				// just stash the descriptive name of the primitive
				std::size_t len = std::min< std::size_t >( prop.GetTopValue().size(), FX_MAX_PRIM_NAME - 1 );
				auto begin = prop.GetTopValue().begin();
				std::copy( begin, begin + len, &mName[ 0 ] );
				mName[ len ] = '\0';
			}
		}
		// Error
		else
		{
			theFxHelper.Print( "Unknown key parsing an effect primitive!\n" );
		}
	}

	for( auto& subGrp : grp.GetSubGroups() )
	{
		using GroupParseMethod = bool ( CPrimitiveTemplate::* )( const CGPGroup& );
		static StringViewIMap< GroupParseMethod > parseMethods{
			{ CSTRING_VIEW( "rgb" ), &CPrimitiveTemplate::ParseRGB },

			{ CSTRING_VIEW( "alpha" ), &CPrimitiveTemplate::ParseAlpha },

			{ CSTRING_VIEW( "size" ), &CPrimitiveTemplate::ParseSize },
			{ CSTRING_VIEW( "width" ), &CPrimitiveTemplate::ParseSize },

			{ CSTRING_VIEW( "size2" ), &CPrimitiveTemplate::ParseSize2 },
			{ CSTRING_VIEW( "width2" ), &CPrimitiveTemplate::ParseSize2 },

			{ CSTRING_VIEW( "length" ), &CPrimitiveTemplate::ParseLength },
			{ CSTRING_VIEW( "height" ), &CPrimitiveTemplate::ParseLength },
		};
		auto pos = parseMethods.find( subGrp.GetName() );
		if( pos == parseMethods.end() )
		{
			theFxHelper.Print( "Unknown group key parsing a particle!\n" );
		}
		else
		{
			GroupParseMethod method = pos->second;
			( this->*method )( subGrp );
		}
	}
	return true;
}