bool CPrimitiveTemplate::ParseGroup( const CGPGroup& grp, const StringViewIMap< ParseMethod >& parseMethods, gsl::czstring name ) { for( auto& cur : grp.GetProperties() ) { auto pos = parseMethods.find( cur.GetName() ); if( pos == parseMethods.end() ) { theFxHelper.Print( "Unknown key parsing %s group!", name ); } else { ParseMethod method = pos->second; ( this->*method )( cur.GetTopValue() ); } } return true; }
// 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; }