diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /vphysics/vcollide_parse.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'vphysics/vcollide_parse.cpp')
| -rw-r--r-- | vphysics/vcollide_parse.cpp | 940 |
1 files changed, 940 insertions, 0 deletions
diff --git a/vphysics/vcollide_parse.cpp b/vphysics/vcollide_parse.cpp new file mode 100644 index 0000000..aa6f772 --- /dev/null +++ b/vphysics/vcollide_parse.cpp @@ -0,0 +1,940 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#include "cbase.h" + +#include "vcollide_parse_private.h" + +#include "tier1/strtools.h" +#include "vphysics/constraints.h" +#include "vphysics/vehicles.h" +#include "filesystem_helpers.h" +#include "bspfile.h" +#include "utlbuffer.h" +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +static void ReadVector( const char *pString, Vector& out ) +{ + float x, y, z; + sscanf( pString, "%f %f %f", &x, &y, &z ); + out[0] = x; + out[1] = y; + out[2] = z; +} + +static void ReadAngles( const char *pString, QAngle& out ) +{ + float x, y, z; + sscanf( pString, "%f %f %f", &x, &y, &z ); + out[0] = x; + out[1] = y; + out[2] = z; +} + +static void ReadVector4D( const char *pString, Vector4D& out ) +{ + float x, y, z, w; + sscanf( pString, "%f %f %f %f", &x, &y, &z, &w ); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; +} + +class CVPhysicsParse : public IVPhysicsKeyParser +{ +public: + ~CVPhysicsParse() {} + + CVPhysicsParse( const char *pKeyData ); + void NextBlock( void ); + + const char *GetCurrentBlockName( void ); + bool Finished( void ); + void ParseSolid( solid_t *pSolid, IVPhysicsKeyHandler *unknownKeyHandler ); + void ParseFluid( fluid_t *pFluid, IVPhysicsKeyHandler *unknownKeyHandler ); + void ParseRagdollConstraint( constraint_ragdollparams_t *pConstraint, IVPhysicsKeyHandler *unknownKeyHandler ); + void ParseSurfaceTable( int *table, IVPhysicsKeyHandler *unknownKeyHandler ); + void ParseSurfaceTablePacked( CUtlVector<char> &out ); + void ParseVehicle( vehicleparams_t *pVehicle, IVPhysicsKeyHandler *unknownKeyHandler ); + void ParseCustom( void *pCustom, IVPhysicsKeyHandler *unknownKeyHandler ); + void SkipBlock( void ) { ParseCustom(NULL, NULL); } + +private: + void ParseVehicleAxle( vehicle_axleparams_t &axle ); + void ParseVehicleWheel( vehicle_wheelparams_t &wheel ); + void ParseVehicleSuspension( vehicle_suspensionparams_t &suspension ); + void ParseVehicleBody( vehicle_bodyparams_t &body ); + void ParseVehicleEngine( vehicle_engineparams_t &engine ); + void ParseVehicleEngineBoost( vehicle_engineparams_t &engine ); + void ParseVehicleSteering( vehicle_steeringparams_t &steering ); + + const char *m_pText; + char m_blockName[MAX_KEYVALUE]; +}; + + +CVPhysicsParse::CVPhysicsParse( const char *pKeyData ) +{ + m_pText = pKeyData; + NextBlock(); +} + +void CVPhysicsParse::NextBlock( void ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( !Q_strcmp(value, "{") ) + { + V_strcpy_safe( m_blockName, key ); + return; + } + } + + // Make sure m_blockName is initialized -- should this be done? + m_blockName[ 0 ] = 0; +} + + +const char *CVPhysicsParse::GetCurrentBlockName( void ) +{ + if ( m_pText ) + return m_blockName; + + return NULL; +} + + +bool CVPhysicsParse::Finished( void ) +{ + if ( m_pText ) + return false; + + return true; +} + + +void CVPhysicsParse::ParseSolid( solid_t *pSolid, IVPhysicsKeyHandler *unknownKeyHandler ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + key[0] = 0; + + if ( unknownKeyHandler ) + { + unknownKeyHandler->SetDefaults( pSolid ); + } + else + { + memset( pSolid, 0, sizeof(*pSolid) ); + } + + // disable these until the ragdoll is created + pSolid->params.enableCollisions = false; + + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + { + NextBlock(); + return; + } + + if ( !Q_stricmp( key, "index" ) ) + { + pSolid->index = atoi(value); + } + else if ( !Q_stricmp( key, "name" ) ) + { + Q_strncpy( pSolid->name, value, sizeof(pSolid->name) ); + } + else if ( !Q_stricmp( key, "parent" ) ) + { + Q_strncpy( pSolid->parent, value, sizeof(pSolid->parent) ); + } + else if ( !Q_stricmp( key, "surfaceprop" ) ) + { + Q_strncpy( pSolid->surfaceprop, value, sizeof(pSolid->surfaceprop) ); + } + else if ( !Q_stricmp( key, "mass" ) ) + { + pSolid->params.mass = atof(value); + } + else if ( !Q_stricmp( key, "massCenterOverride" ) ) + { + ReadVector( value, pSolid->massCenterOverride ); + pSolid->params.massCenterOverride = &pSolid->massCenterOverride; + } + else if ( !Q_stricmp( key, "inertia" ) ) + { + pSolid->params.inertia = atof(value); + } + else if ( !Q_stricmp( key, "damping" ) ) + { + pSolid->params.damping = atof(value); + } + else if ( !Q_stricmp( key, "rotdamping" ) ) + { + pSolid->params.rotdamping = atof(value); + } + else if ( !Q_stricmp( key, "volume" ) ) + { + pSolid->params.volume = atof(value); + } + else if ( !Q_stricmp( key, "drag" ) ) + { + pSolid->params.dragCoefficient = atof(value); + } + else if ( !Q_stricmp( key, "rollingdrag" ) ) + { + //pSolid->params.rollingDrag = atof(value); + } + else + { + if ( unknownKeyHandler ) + { + unknownKeyHandler->ParseKeyValue( pSolid, key, value ); + } + } + } +} + +void CVPhysicsParse::ParseRagdollConstraint( constraint_ragdollparams_t *pConstraint, IVPhysicsKeyHandler *unknownKeyHandler ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + if ( unknownKeyHandler ) + { + unknownKeyHandler->SetDefaults( pConstraint ); + } + else + { + memset( pConstraint, 0, sizeof(*pConstraint) ); + pConstraint->childIndex = -1; + pConstraint->parentIndex = -1; + } + + // BUGBUG: xmin/xmax, ymin/ymax, zmin/zmax specify clockwise rotations. + // BUGBUG: HL rotations are counter-clockwise, so reverse these limits at some point!!! + pConstraint->useClockwiseRotations = true; + + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + { + NextBlock(); + return; + } + + if ( !Q_stricmp( key, "parent" ) ) + { + pConstraint->parentIndex = atoi( value ); + } + else if ( !Q_stricmp( key, "child" ) ) + { + pConstraint->childIndex = atoi( value ); + } + else if ( !Q_stricmp( key, "xmin" ) ) + { + pConstraint->axes[0].minRotation = atof( value ); + } + else if ( !Q_stricmp( key, "xmax" ) ) + { + pConstraint->axes[0].maxRotation = atof( value ); + } + else if ( !Q_stricmp( key, "xfriction" ) ) + { + pConstraint->axes[0].angularVelocity = 0; + pConstraint->axes[0].torque = atof( value ); + } + else if ( !Q_stricmp( key, "ymin" ) ) + { + pConstraint->axes[1].minRotation = atof( value ); + } + else if ( !Q_stricmp( key, "ymax" ) ) + { + pConstraint->axes[1].maxRotation = atof( value ); + } + else if ( !Q_stricmp( key, "yfriction" ) ) + { + pConstraint->axes[1].angularVelocity = 0; + pConstraint->axes[1].torque = atof( value ); + } + else if ( !Q_stricmp( key, "zmin" ) ) + { + pConstraint->axes[2].minRotation = atof( value ); + } + else if ( !Q_stricmp( key, "zmax" ) ) + { + pConstraint->axes[2].maxRotation = atof( value ); + } + else if ( !Q_stricmp( key, "zfriction" ) ) + { + pConstraint->axes[2].angularVelocity = 0; + pConstraint->axes[2].torque = atof( value ); + } + else + { + if ( unknownKeyHandler ) + { + unknownKeyHandler->ParseKeyValue( pConstraint, key, value ); + } + } + } +} + + +void CVPhysicsParse::ParseFluid( fluid_t *pFluid, IVPhysicsKeyHandler *unknownKeyHandler ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + pFluid->index = -1; + if ( unknownKeyHandler ) + { + unknownKeyHandler->SetDefaults( pFluid ); + } + else + { + memset( pFluid, 0, sizeof(*pFluid) ); + // HACKHACK: This is a reasonable default even though it is hardcoded + V_strcpy_safe( pFluid->surfaceprop, "water" ); + } + + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + { + NextBlock(); + return; + } + + if ( !Q_stricmp( key, "index" ) ) + { + pFluid->index = atoi( value ); + } + else if ( !Q_stricmp( key, "damping" ) ) + { + pFluid->params.damping = atof( value ); + } + else if ( !Q_stricmp( key, "surfaceplane" ) ) + { + ReadVector4D( value, pFluid->params.surfacePlane ); + } + else if ( !Q_stricmp( key, "currentvelocity" ) ) + { + ReadVector( value, pFluid->params.currentVelocity ); + } + else if ( !Q_stricmp( key, "contents" ) ) + { + pFluid->params.contents = atoi( value ); + } + else if ( !Q_stricmp( key, "surfaceprop" ) ) + { + Q_strncpy( pFluid->surfaceprop, value, sizeof(pFluid->surfaceprop) ); + } + else + { + if ( unknownKeyHandler ) + { + unknownKeyHandler->ParseKeyValue( pFluid, key, value ); + } + } + } +} + +void CVPhysicsParse::ParseSurfaceTable( int *table, IVPhysicsKeyHandler *unknownKeyHandler ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + { + NextBlock(); + return; + } + + int propIndex = physprops->GetSurfaceIndex( key ); + int tableIndex = atoi(value); + if ( tableIndex >= 0 && tableIndex < 128 ) + { + table[tableIndex] = propIndex; + } + } +} + +void CVPhysicsParse::ParseSurfaceTablePacked( CUtlVector<char> &out ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + int lastIndex = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + { + NextBlock(); + return; + } + + int len = Q_strlen( key ); + int outIndex = out.AddMultipleToTail( len + 1 ); + memcpy( &out[outIndex], key, len+1 ); + int tableIndex = atoi(value); + Assert( tableIndex == lastIndex + 1); + lastIndex = tableIndex; + } +} + +void CVPhysicsParse::ParseVehicleAxle( vehicle_axleparams_t &axle ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + memset( &axle, 0, sizeof(axle) ); + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + + // parse subchunks + if ( value[0] == '{' ) + { + if ( !Q_stricmp( key, "wheel" ) ) + { + ParseVehicleWheel( axle.wheels ); + } + else if ( !Q_stricmp( key, "suspension" ) ) + { + ParseVehicleSuspension( axle.suspension ); + } + else + { + SkipBlock(); + } + } + else if ( !Q_stricmp( key, "offset" ) ) + { + ReadVector( value, axle.offset ); + } + else if ( !Q_stricmp( key, "wheeloffset" ) ) + { + ReadVector( value, axle.wheelOffset ); + } + else if ( !Q_stricmp( key, "torquefactor" ) ) + { + axle.torqueFactor = atof( value ); + } + else if ( !Q_stricmp( key, "brakefactor" ) ) + { + axle.brakeFactor = atof( value ); + } + } +} + +void CVPhysicsParse::ParseVehicleWheel( vehicle_wheelparams_t &wheel ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + + if ( !Q_stricmp( key, "radius" ) ) + { + wheel.radius = atof( value ); + } + else if ( !Q_stricmp( key, "mass" ) ) + { + wheel.mass = atof( value ); + } + else if ( !Q_stricmp( key, "inertia" ) ) + { + wheel.inertia = atof( value ); + } + else if ( !Q_stricmp( key, "damping" ) ) + { + wheel.damping = atof( value ); + } + else if ( !Q_stricmp( key, "rotdamping" ) ) + { + wheel.rotdamping = atof( value ); + } + else if ( !Q_stricmp( key, "frictionscale" ) ) + { + wheel.frictionScale = atof( value ); + } + else if ( !Q_stricmp( key, "material" ) ) + { + wheel.materialIndex = physprops->GetSurfaceIndex( value ); + } + else if ( !Q_stricmp( key, "skidmaterial" ) ) + { + wheel.skidMaterialIndex = physprops->GetSurfaceIndex( value ); + } + else if ( !Q_stricmp( key, "brakematerial" ) ) + { + wheel.brakeMaterialIndex = physprops->GetSurfaceIndex( value ); + } + } +} + + +void CVPhysicsParse::ParseVehicleSuspension( vehicle_suspensionparams_t &suspension ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + + if ( !Q_stricmp( key, "springconstant" ) ) + { + suspension.springConstant = atof( value ); + } + else if ( !Q_stricmp( key, "springdamping" ) ) + { + suspension.springDamping = atof( value ); + } + else if ( !Q_stricmp( key, "stabilizerconstant" ) ) + { + suspension.stabilizerConstant = atof( value ); + } + else if ( !Q_stricmp( key, "springdampingcompression" ) ) + { + suspension.springDampingCompression = atof( value ); + } + else if ( !Q_stricmp( key, "maxbodyforce" ) ) + { + suspension.maxBodyForce = atof( value ); + } + } +} + + +void CVPhysicsParse::ParseVehicleBody( vehicle_bodyparams_t &body ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + + if ( !Q_stricmp( key, "massCenterOverride" ) ) + { + ReadVector( value, body.massCenterOverride ); + } + else if ( !Q_stricmp( key, "addgravity" ) ) + { + body.addGravity = atof( value ); + } + else if ( !Q_stricmp( key, "maxAngularVelocity" ) ) + { + body.maxAngularVelocity = atof( value ); + } + else if ( !Q_stricmp( key, "massOverride" ) ) + { + body.massOverride = atof( value ); + } + else if ( !Q_stricmp( key, "tiltforce" ) ) + { + body.tiltForce = atof( value ); + } + else if ( !Q_stricmp( key, "tiltforceheight" ) ) + { + body.tiltForceHeight = atof( value ); + } + else if ( !Q_stricmp( key, "countertorquefactor" ) ) + { + body.counterTorqueFactor = atof( value ); + } + else if ( !Q_stricmp( key, "keepuprighttorque" ) ) + { + body.keepUprightTorque = atof( value ); + } + } +} + + +void CVPhysicsParse::ParseVehicleEngineBoost( vehicle_engineparams_t &engine ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + // parse subchunks + if ( !Q_stricmp( key, "force" ) ) + { + engine.boostForce = atof( value ); + } + else if ( !Q_stricmp( key, "duration" ) ) + { + engine.boostDuration = atof( value ); + } + else if ( !Q_stricmp( key, "delay" ) ) + { + engine.boostDelay = atof( value ); + } + else if ( !Q_stricmp( key, "maxspeed" ) ) + { + engine.boostMaxSpeed = atof( value ); + } + else if ( !Q_stricmp( key, "torqueboost" ) ) + { + engine.torqueBoost = atoi( value ) != 0 ? true : false; + } + + } +} + +void CVPhysicsParse::ParseVehicleEngine( vehicle_engineparams_t &engine ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + // parse subchunks + if ( value[0] == '{' ) + { + if ( !Q_stricmp( key, "boost" ) ) + { + ParseVehicleEngineBoost( engine ); + } + else + { + SkipBlock(); + } + } + else if ( !Q_stricmp( key, "gear" ) ) + { + // Protect against exploits/overruns + if ( engine.gearCount < ARRAYSIZE(engine.gearRatio) ) + { + engine.gearRatio[engine.gearCount] = atof( value ); + engine.gearCount++; + } + else + { + Assert( 0 ); + } + } + else if ( !Q_stricmp( key, "horsepower" ) ) + { + engine.horsepower = atof( value ); + } + else if ( !Q_stricmp( key, "maxSpeed" ) ) + { + engine.maxSpeed = atof( value ); + } + else if ( !Q_stricmp( key, "maxReverseSpeed" ) ) + { + engine.maxRevSpeed = atof( value ); + } + else if ( !Q_stricmp( key, "axleratio" ) ) + { + engine.axleRatio = atof( value ); + } + else if ( !Q_stricmp( key, "maxRPM" ) ) + { + engine.maxRPM = atof( value ); + } + else if ( !Q_stricmp( key, "throttleTime" ) ) + { + engine.throttleTime = atof( value ); + } + else if ( !Q_stricmp( key, "AutoTransmission" ) ) + { + engine.isAutoTransmission = atoi( value ) != 0 ? true : false; + } + else if ( !Q_stricmp( key, "shiftUpRPM" ) ) + { + engine.shiftUpRPM = atof( value ); + } + else if ( !Q_stricmp( key, "shiftDownRPM" ) ) + { + engine.shiftDownRPM = atof( value ); + } + else if ( !Q_stricmp( key, "autobrakeSpeedGain" ) ) + { + engine.autobrakeSpeedGain = atof( value ); + } + else if ( !Q_stricmp( key, "autobrakeSpeedFactor" ) ) + { + engine.autobrakeSpeedFactor = atof( value ); + } + } +} + + +void CVPhysicsParse::ParseVehicleSteering( vehicle_steeringparams_t &steering ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + return; + // parse subchunks + if ( !Q_stricmp( key, "degreesSlow" ) ) + { + steering.degreesSlow = atof( value ); + } + else if ( !Q_stricmp( key, "degreesFast" ) ) + { + steering.degreesFast = atof( value ); + } + else if ( !Q_stricmp( key, "degreesBoost" ) ) + { + steering.degreesBoost = atof( value ); + } + else if ( !Q_stricmp( key, "fastcarspeed" ) ) + { + steering.speedFast = atof( value ); + } + else if ( !Q_stricmp( key, "slowcarspeed" ) ) + { + steering.speedSlow = atof( value ); + } + else if ( !Q_stricmp( key, "slowsteeringrate" ) ) + { + steering.steeringRateSlow = atof( value ); + } + else if ( !Q_stricmp( key, "faststeeringrate" ) ) + { + steering.steeringRateFast = atof( value ); + } + else if ( !Q_stricmp( key, "steeringRestRateSlow" ) ) + { + steering.steeringRestRateSlow = atof( value ); + } + else if ( !Q_stricmp( key, "steeringRestRateFast" ) ) + { + steering.steeringRestRateFast = atof( value ); + } + else if ( !Q_stricmp( key, "throttleSteeringRestRateFactor" ) ) + { + steering.throttleSteeringRestRateFactor = atof( value ); + } + else if ( !Q_stricmp( key, "boostSteeringRestRateFactor" ) ) + { + steering.boostSteeringRestRateFactor = atof( value ); + } + else if ( !Q_stricmp( key, "boostSteeringRateFactor" ) ) + { + steering.boostSteeringRateFactor = atof( value ); + } + else if ( !Q_stricmp( key, "steeringExponent" ) ) + { + steering.steeringExponent = atof( value ); + } + else if ( !Q_stricmp( key, "turnThrottleReduceSlow" ) ) + { + steering.turnThrottleReduceSlow = atof( value ); + } + else if ( !Q_stricmp( key, "turnThrottleReduceFast" ) ) + { + steering.turnThrottleReduceFast = atof( value ); + } + else if ( !Q_stricmp( key, "brakeSteeringRateFactor" ) ) + { + steering.brakeSteeringRateFactor = atof( value ); + } + else if ( !Q_stricmp( key, "powerSlideAccel" ) ) + { + steering.powerSlideAccel = atof( value ); + } + else if ( !Q_stricmp( key, "skidallowed" ) ) + { + steering.isSkidAllowed = atoi( value ) != 0 ? true : false; + } + else if ( !Q_stricmp( key, "dustcloud" ) ) + { + steering.dustCloud = atoi( value ) != 0 ? true : false; + } + } +} + +void CVPhysicsParse::ParseVehicle( vehicleparams_t *pVehicle, IVPhysicsKeyHandler *unknownKeyHandler ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + if ( unknownKeyHandler ) + { + unknownKeyHandler->SetDefaults( pVehicle ); + } + else + { + memset( pVehicle, 0, sizeof(*pVehicle) ); + } + + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + if ( key[0] == '}' ) + { + NextBlock(); + return; + } + + // parse subchunks + if ( value[0] == '{' ) + { + if ( !Q_stricmp( key, "axle" ) ) + { + // Protect against exploits/overruns + if ( pVehicle->axleCount < ARRAYSIZE(pVehicle->axles) ) + { + ParseVehicleAxle( pVehicle->axles[pVehicle->axleCount] ); + pVehicle->axleCount++; + } + else + { + Assert( 0 ); + } + } + else if ( !Q_stricmp( key, "body" ) ) + { + ParseVehicleBody( pVehicle->body ); + } + else if ( !Q_stricmp( key, "engine" ) ) + { + ParseVehicleEngine( pVehicle->engine ); + } + else if ( !Q_stricmp( key, "steering" ) ) + { + ParseVehicleSteering( pVehicle->steering ); + } + else + { + SkipBlock(); + } + } + else if ( !Q_stricmp( key, "wheelsperaxle" ) ) + { + pVehicle->wheelsPerAxle = atoi( value ); + } + } +} + +void CVPhysicsParse::ParseCustom( void *pCustom, IVPhysicsKeyHandler *unknownKeyHandler ) +{ + char key[MAX_KEYVALUE], value[MAX_KEYVALUE]; + + key[0] = 0; + int indent = 0; + if ( unknownKeyHandler ) + { + unknownKeyHandler->SetDefaults( pCustom ); + } + + while ( m_pText ) + { + m_pText = ParseKeyvalue( m_pText, key, value ); + + if ( m_pText ) + { + if ( key[0] == '{' ) + { + indent++; + } + else if ( value[0] == '{' ) + { + // They've got a named block here + // Increase our indent, and let them parse the key + indent++; + if ( unknownKeyHandler ) + { + unknownKeyHandler->ParseKeyValue( pCustom, key, value ); + } + } + else if ( key[0] == '}' ) + { + indent--; + if ( indent < 0 ) + { + NextBlock(); + return; + } + } + else + { + if ( unknownKeyHandler ) + { + unknownKeyHandler->ParseKeyValue( pCustom, key, value ); + } + } + } + } +} + +IVPhysicsKeyParser *CreateVPhysicsKeyParser( const char *pKeyData ) +{ + return new CVPhysicsParse( pKeyData ); +} + +void DestroyVPhysicsKeyParser( IVPhysicsKeyParser *pParser ) +{ + delete pParser; +} + +//----------------------------------------------------------------------------- +// Helper functions for parsing script file +//----------------------------------------------------------------------------- + +const char *ParseKeyvalue( const char *pBuffer, char (&key)[MAX_KEYVALUE], char (&value)[MAX_KEYVALUE] ) +{ + // Make sure value is always null-terminated. + value[0] = 0; + + pBuffer = ParseFile( pBuffer, key, NULL ); + + // no value on a close brace + if ( key[0] == '}' && key[1] == 0 ) + { + value[0] = 0; + return pBuffer; + } + + Q_strlower( key ); + + pBuffer = ParseFile( pBuffer, value, NULL ); + + Q_strlower( value ); + + return pBuffer; +} |