That workaround fails when the view ray is nearly parallel to a surface the camera ends close to and the c_trace did not collide to.

The only solution I know is the use of a dummy entity and USE_BOX in the trace.

Code:
action actCameraCollider () {
   proc_mode = PROC_LATE; // execute after player action
   my->flags |= INVISIBLE | PASSABLE | FAT | NARROW;
   vec_set(&my->max_x, vector(16, 16, 16)); // collision hull
   vec_set(&my->min_x, vector(-16, -16, -16));
   VECTOR vOffset;
   vec_set(&vOffset, vector(0, -7, 35));  // camera rotation center in player space
   var nCamDist = 200; // distance to the center
   ...
   vec_set(&my->x, &vOffset); // set the collider position in reference to the player position and orientation
   vec_rotate(&my->x, &player->pan);
   vec_add(&my->x, &player->x);
   VECTOR vDir;
   vec_for_angle(&vDir, &camera->pan); // compute the inverse of the view ray; the trace is backwards
   vec_scale(&vDir, -nCamDist);
   VECTOR vTarget; // compute the target position for c_trace
   vec_set(&vTarget, &my->x); // it is also the final camera position when the trace collides nothing
   vec_add(&vTarget, &vDir);
   you = player; 
   var nDist = c_trace(&my->x, &vTarget, IGNORE_YOU | IGNORE_PASSABLE | USE_BOX);
   if (nDist > 0) { // when it collides
      vec_normalize(&vDir, nDist); // enshort the view ray
      vec_set(&camera->x, &my->x); // and recompute the position of the camera
      vec_add(&camera->x, &vDir);
   } else { // when it does not collide
      vec_set(&camera->x, &vTarget); // set the already computed position of the camera
   }
   ...



Salud!