eClientVehicleType CClientVehicleManager::GetVehicleType ( unsigned long ulModel )
{
    // Valid vehicle id?
    if ( IsValidModel ( ulModel ) )
    {
        // Grab the model info for the current vehicle
        CModelInfo* pModelInfo = g_pGame->GetModelInfo ( ulModel );
        if ( pModelInfo )
        {
            // Return the appropriate type
            if ( pModelInfo->IsCar () ) return CLIENTVEHICLE_CAR;
            if ( pModelInfo->IsBike () ) return CLIENTVEHICLE_BIKE;
            if ( pModelInfo->IsPlane () ) return CLIENTVEHICLE_PLANE;
            if ( pModelInfo->IsHeli () ) return CLIENTVEHICLE_HELI;
            if ( pModelInfo->IsBoat () ) return CLIENTVEHICLE_BOAT;
            if ( pModelInfo->IsQuadBike () ) return CLIENTVEHICLE_QUADBIKE;
            if ( pModelInfo->IsBmx () ) return CLIENTVEHICLE_BMX;
            if ( pModelInfo->IsMonsterTruck () ) return CLIENTVEHICLE_MONSTERTRUCK;
            if ( pModelInfo->IsTrailer () ) return CLIENTVEHICLE_TRAILER;
            if ( pModelInfo->IsTrain () ) return CLIENTVEHICLE_TRAIN;
        }
    }

    // Invalid vehicle id or some other error
    return CLIENTVEHICLE_NONE;
}
void CHandlingRPCs::SetVehicleHandling ( CClientEntity* pSource, NetBitStreamInterface& bitStream )
{
    // Check it's type
    if ( pSource && pSource->GetType () == CCLIENTVEHICLE )
    {
        // Grab the vehicle handling entry
        CClientVehicle& Vehicle = static_cast < CClientVehicle& > ( *pSource );
        CHandlingEntry* pEntry = Vehicle.GetHandlingData();
        CModelInfo * pModelInfo = Vehicle.GetModelInfo ( );
        
        bool bReadSuspension = false;
        if ( pModelInfo )
            bReadSuspension = pModelInfo->IsCar ( ) || pModelInfo->IsMonsterTruck();

        SVehicleHandlingSync handling;
        bitStream.Read ( &handling );
        pEntry->SetMass ( handling.data.fMass );
        pEntry->SetTurnMass ( handling.data.fTurnMass );
        pEntry->SetDragCoeff ( handling.data.fDragCoeff );
        pEntry->SetCenterOfMass ( handling.data.vecCenterOfMass );
        pEntry->SetPercentSubmerged ( handling.data.ucPercentSubmerged );
        pEntry->SetTractionMultiplier ( handling.data.fTractionMultiplier );
        pEntry->SetCarDriveType ( (CHandlingEntry::eDriveType)handling.data.ucDriveType );
        pEntry->SetCarEngineType ( (CHandlingEntry::eEngineType)handling.data.ucEngineType );
        pEntry->SetNumberOfGears ( handling.data.ucNumberOfGears );
        pEntry->SetEngineAcceleration ( handling.data.fEngineAcceleration );
        pEntry->SetEngineInertia ( handling.data.fEngineInertia );
        pEntry->SetMaxVelocity ( handling.data.fMaxVelocity );
        pEntry->SetBrakeDeceleration ( handling.data.fBrakeDeceleration );
        pEntry->SetBrakeBias ( handling.data.fBrakeBias );
        pEntry->SetABS ( handling.data.bABS );
        pEntry->SetSteeringLock ( handling.data.fSteeringLock );
        pEntry->SetTractionLoss ( handling.data.fTractionLoss );
        pEntry->SetTractionBias ( handling.data.fTractionBias );
        if ( bReadSuspension )
        {
            pEntry->SetSuspensionForceLevel ( handling.data.fSuspensionForceLevel );
            pEntry->SetSuspensionDamping ( handling.data.fSuspensionDamping );
            pEntry->SetSuspensionHighSpeedDamping ( handling.data.fSuspensionHighSpdDamping );
            pEntry->SetSuspensionUpperLimit ( handling.data.fSuspensionUpperLimit );
            pEntry->SetSuspensionLowerLimit ( handling.data.fSuspensionLowerLimit );
            pEntry->SetSuspensionFrontRearBias ( handling.data.fSuspensionFrontRearBias );
            pEntry->SetSuspensionAntiDiveMultiplier ( handling.data.fSuspensionAntiDiveMultiplier );
        }
        pEntry->SetCollisionDamageMultiplier ( handling.data.fCollisionDamageMultiplier );
        pEntry->SetModelFlags ( handling.data.uiModelFlags );
        pEntry->SetHandlingFlags ( handling.data.uiHandlingFlags );
        pEntry->SetSeatOffsetDistance ( handling.data.fSeatOffsetDistance );
        //pEntry->SetMonetary ( handling.data.uiMonetary );
        //pEntry->SetHeadLight ( (CHandlingEntry::eLightType)handling.data.ucHeadLight );
        //pEntry->SetTailLight ( (CHandlingEntry::eLightType)handling.data.ucTailLight );
        //pEntry->SetAnimGroup ( handling.data.ucAnimGroup );
        
        Vehicle.ApplyHandling();
    }
}
void CHandlingRPCs::SetVehicleHandlingProperty ( CClientEntity* pSource, NetBitStreamInterface& bitStream )
{
    // Read out the property id
    unsigned char ucProperty;
    if ( bitStream.Read ( ucProperty ) )
    {
        // Check its type
        if ( pSource && pSource->GetType () == CCLIENTVEHICLE )
        {
            // Grab the vehicle handling entry
            CClientVehicle& vehicle = static_cast < CClientVehicle& > ( *pSource );
            CHandlingEntry* pHandlingEntry = vehicle.GetHandlingData ( );
            CModelInfo * pModelInfo = vehicle.GetModelInfo ( );

            bool bReadSuspension = false;
            if ( pModelInfo )
                bReadSuspension = pModelInfo->IsCar ( ) || pModelInfo->IsMonsterTruck ( );

            // Temporary storage for reading out data
            union
            {
                unsigned char ucChar;
                unsigned int uiInt;
                float fFloat;
            };

            // Depending on what property
            switch ( ucProperty )
            {
                case HANDLING_MASS:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetMass ( fFloat );
                    break;
                    
                case HANDLING_TURNMASS:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetTurnMass ( fFloat );
                    break;

                case HANDLING_DRAGCOEFF:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetDragCoeff ( fFloat );
                    break;

                case HANDLING_CENTEROFMASS:
                {
                    CVector vecVector;
                    bitStream.Read ( vecVector.fX );
                    bitStream.Read ( vecVector.fY );
                    bitStream.Read ( vecVector.fZ );
                    pHandlingEntry->SetCenterOfMass ( vecVector );
                    break;
                }

                case HANDLING_PERCENTSUBMERGED:
                    bitStream.Read ( uiInt );
                    pHandlingEntry->SetPercentSubmerged ( uiInt );
                    break;

                case HANDLING_TRACTIONMULTIPLIER:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetTractionMultiplier ( fFloat );
                    break;

                case HANDLING_DRIVETYPE:
                {
                    bitStream.Read ( ucChar );
                    if ( ucChar != CHandlingEntry::FOURWHEEL &&
                         ucChar != CHandlingEntry::RWD &&
                         ucChar != CHandlingEntry::FWD )
                    {
                        ucChar = CHandlingEntry::RWD;
                    }

                    pHandlingEntry->SetCarDriveType ( static_cast < CHandlingEntry::eDriveType > ( ucChar ) );
                    break;
                }

                case HANDLING_ENGINETYPE:
                {
                    bitStream.Read ( ucChar );
                    if ( ucChar != CHandlingEntry::DIESEL &&
                         ucChar != CHandlingEntry::ELECTRIC &&
                         ucChar != CHandlingEntry::PETROL )
                    {
                        ucChar = CHandlingEntry::PETROL;
                    }

                    pHandlingEntry->SetCarEngineType ( static_cast < CHandlingEntry::eEngineType > ( ucChar ) );
                    break;
                }

                case HANDLING_NUMOFGEARS:
                    bitStream.Read ( ucChar );
                    pHandlingEntry->SetNumberOfGears ( ucChar );
                    break;

                case HANDLING_ENGINEACCELERATION:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetEngineAcceleration ( fFloat );
                    break;

                case HANDLING_ENGINEINERTIA:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetEngineInertia ( fFloat );
                    break;

                case HANDLING_MAXVELOCITY:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetMaxVelocity ( fFloat );
                    break;

                case HANDLING_BRAKEDECELERATION:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetBrakeDeceleration ( fFloat );
                    break;

                case HANDLING_BRAKEBIAS:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetBrakeBias ( fFloat );
                    break;

                case HANDLING_ABS:
                    bitStream.Read ( ucChar );
                    pHandlingEntry->SetABS ( ucChar != 0 );
                    break;

                case HANDLING_STEERINGLOCK:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetSteeringLock ( fFloat );
                    break;

                case HANDLING_TRACTIONLOSS:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetTractionLoss ( fFloat );
                    break;

                case HANDLING_TRACTIONBIAS:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetTractionBias ( fFloat );
                    break;

                case HANDLING_SUSPENSION_FORCELEVEL:
                {

                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionForceLevel ( fFloat );
                    }
                    break;
                }

                case HANDLING_SUSPENSION_DAMPING:
                {
                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionDamping ( fFloat );
                    }
                    break;
                }

                case HANDLING_SUSPENSION_HIGHSPEEDDAMPING:
                {
                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionHighSpeedDamping ( fFloat );
                    }
                    break;
                }

                case HANDLING_SUSPENSION_UPPER_LIMIT:
                {
                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionUpperLimit ( fFloat );
                    }
                    break;
                }

                case HANDLING_SUSPENSION_LOWER_LIMIT:
                {
                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionLowerLimit ( fFloat );
                    }
                    break;
                }

                case HANDLING_SUSPENSION_FRONTREARBIAS:
                {
                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionFrontRearBias ( fFloat );
                    }
                    break;
                }

                case HANDLING_SUSPENSION_ANTIDIVEMULTIPLIER:
                {
                    bitStream.Read ( fFloat );
                    if ( bReadSuspension )
                    {
                        pHandlingEntry->SetSuspensionAntiDiveMultiplier ( fFloat );
                    }
                    break;
                }

                case HANDLING_COLLISIONDAMAGEMULTIPLIER:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetCollisionDamageMultiplier ( fFloat );
                    break;

                case HANDLING_SEATOFFSETDISTANCE:
                    bitStream.Read ( fFloat );
                    pHandlingEntry->SetSeatOffsetDistance ( fFloat );
                    break;

                /*case HANDLING_MONETARY:
                    bitStream.Read ( uiInt );
                    pHandlingEntry->SetMonetary ( uiInt );
                    break;*/

                case HANDLING_HANDLINGFLAGS:
                    bitStream.Read ( uiInt );
                    pHandlingEntry->SetHandlingFlags ( uiInt );
                    break;

                case HANDLING_MODELFLAGS:
                    bitStream.Read ( uiInt );
                    pHandlingEntry->SetModelFlags ( uiInt );
                    break;

                /*case HANDLING_HEADLIGHT:
                    bitStream.Read ( ucChar );
                    if ( ucChar > CHandlingEntry::TALL )
                        ucChar = CHandlingEntry::TALL;

                    pHandlingEntry->SetHeadLight ( static_cast < CHandlingEntry::eLightType > ( ucChar ) );
                    break;

                case HANDLING_TAILLIGHT:
                    bitStream.Read ( ucChar );
                    if ( ucChar > CHandlingEntry::TALL ) 
                        ucChar = CHandlingEntry::TALL;

                    pHandlingEntry->SetTailLight ( static_cast < CHandlingEntry::eLightType > ( ucChar ) );
                    break;*/

                case HANDLING_ANIMGROUP:
                    bitStream.Read ( ucChar );
                    //pHandlingEntry->SetAnimGroup ( ucChar );
                    break;
            }

            vehicle.ApplyHandling();
        }
    }
}