+ else
+ {
+ // player can look around, so take the origin from the entity,
+ // and the angles from the input system
+ Matrix4x4_OriginFromMatrix(&ent->render.matrix, vieworg);
+ VectorCopy(cl.viewangles, viewangles);
+
+ // stair smoothing
+ //Con_Printf("cl.onground %i oldz %f newz %f\n", cl.onground, oldz, vieworg[2]);
+ if (cl.onground && oldz < vieworg[2])
+ {
+ oldz += (cl.time - cl.oldtime) * cl_stairsmoothspeed.value;
+ oldz = vieworg[2] = bound(vieworg[2] - 16, oldz, vieworg[2]);
+ }
+ else if (cl.onground && oldz > vieworg[2])
+ {
+ oldz -= (cl.time - cl.oldtime) * cl_stairsmoothspeed.value;
+ oldz = vieworg[2] = bound(vieworg[2], oldz, vieworg[2] + 16);
+ }
+ else
+ oldz = vieworg[2];
+
+ if (chase_active.value)
+ {
+ // observing entity from third person
+ vec_t camback, camup, dist, forward[3], chase_dest[3];
+
+ camback = bound(0, chase_back.value, 128);
+ if (chase_back.value != camback)
+ Cvar_SetValueQuick(&chase_back, camback);
+ camup = bound(-48, chase_up.value, 96);
+ if (chase_up.value != camup)
+ Cvar_SetValueQuick(&chase_up, camup);
+
+ // this + 22 is to match view_ofs for compatibility with older versions
+ camup += 22;
+
+ if (gamemode == GAME_GOODVSBAD2 && chase_stevie.integer)
+ {
+ // look straight down from high above
+ viewangles[0] = 90;
+ camback = 2048;
+ }
+ AngleVectors(viewangles, forward, NULL, NULL);
+
+ // trace a little further so it hits a surface more consistently (to avoid 'snapping' on the edge of the range)
+ dist = -camback - 8;
+ chase_dest[0] = vieworg[0] + forward[0] * dist;
+ chase_dest[1] = vieworg[1] + forward[1] * dist;
+ chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
+ trace = CL_TraceBox(vieworg, vec3_origin, vec3_origin, chase_dest, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+ VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
+ }
+ else