IMotionEvent::simresult_e CPhysicsNPCSolver::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, float deltaTime, Vector &linear, AngularImpulse &angular ) { if ( IsIntersecting() ) { const float PUSH_SPEED = 150.0f; if ( pObject->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( pPlayer ) { pPlayer->ForceDropOfCarriedPhysObjects( m_hEntity ); } } ResetCancelTime(); angular.Init(); linear.Init(); // Don't push on vehicles because they won't move if ( pObject->GetGameFlags() & FVPHYSICS_MULTIOBJECT_ENTITY ) { if ( m_hEntity->GetServerVehicle() ) return SIM_NOTHING; } Vector origin, vel; pObject->GetPosition( &origin, NULL ); pObject->GetVelocity( &vel, NULL ); Vector dir = origin - m_hNPC->GetAbsOrigin(); dir.z = dir.z > 0 ? 0.1f : -0.1f; VectorNormalize(dir); AngularImpulse angVel; angVel.Init(); // NOTE: Iterate this object's contact points // if it can't move in this direction, try sliding along the plane/crease Vector pushImpulse; PhysComputeSlideDirection( pObject, dir * PUSH_SPEED, angVel, &pushImpulse, NULL, 0 ); dir = pushImpulse; VectorNormalize(dir); if ( DotProduct( vel, dir ) < PUSH_SPEED * 0.5f ) { linear = pushImpulse; if ( pObject->GetContactPoint(NULL,NULL) ) { linear.z += GetCurrentGravity(); } } return SIM_GLOBAL_ACCELERATION; } return SIM_NOTHING; }