+ // use traces to determine what range the view can bob in, and scale down the bob as needed
+ float trace1fraction;
+ float trace2fraction;
+ vec3_t bob_height_check_dest;
+
+ // these multipliers are expanded a bit (the actual bob sin range is from -0.4 to 1.0) to reduce nearclip issues, especially on water surfaces
+ bob_height_check_dest[0] = vieworg[0];
+ bob_height_check_dest[1] = vieworg[1];
+ bob_height_check_dest[2] = vieworg[2] + cl_bob_limit.value * 1.1f;
+ trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true);
+ trace1fraction = trace.fraction;
+
+ bob_height_check_dest[0] = vieworg[0];
+ bob_height_check_dest[1] = vieworg[1];
+ bob_height_check_dest[2] = vieworg[2] + cl_bob_limit.value * -0.5f;
+ trace = CL_TraceLine(vieworg, bob_height_check_dest, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY | (cl_bob_limit_heightcheck_dontcrosswatersurface.integer ? SUPERCONTENTS_LIQUIDSMASK : 0), 0, MATERIALFLAGMASK_TRANSLUCENT, collision_extendmovelength.value, true, false, NULL, false, true);
+ trace2fraction = trace.fraction;
+
+ bob_limit *= min(trace1fraction, trace2fraction);
+ }
+
+ // LordHavoc: this code is *weird*, but not replacable (I think it
+ // should be done in QC on the server, but oh well, quake is quake)
+ // LordHavoc: figured out bobup: the time at which the sin is at 180
+ // degrees (which allows lengthening or squishing the peak or valley)
+ cycle = cl.time / cl_bobcycle.value;
+ cycle -= (int) cycle;
+ if (cycle < cl_bobup.value)
+ cycle = sin(M_PI * cycle / cl_bobup.value);
+ else
+ cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
+ // bob is proportional to velocity in the xy plane
+ // (don't count Z, or jumping messes it up)
+ bob = xyspeed * cl_bob.value;
+ bob = bound(0, bob, bob_limit);
+ bob = bob*0.3 + bob*0.7*cycle;
+ vieworg[2] += bob;
+ // we also need to adjust gunorg, or this appears like pushing the gun!
+ // In the old code, this was applied to vieworg BEFORE copying to gunorg,
+ // but this is not viable with the new followmodel code as that would mean
+ // that followmodel would work on the munged-by-bob vieworg and do feedback
+ gunorg[2] += bob;
+ }
+
+ // horizontal view bobbing code
+ if (cl_bob2.value && cl_bob2cycle.value)
+ {
+ vec3_t bob2vel;
+ vec3_t forward, right, up;
+ float side, front;
+
+ cycle = cl.time / cl_bob2cycle.value;
+ cycle -= (int) cycle;
+ if (cycle < 0.5)
+ cycle = cos(M_PI * cycle / 0.5); // cos looks better here with the other view bobbing using sin
+ else
+ cycle = cos(M_PI + M_PI * (cycle-0.5)/0.5);
+ bob = cl_bob2.value * cycle;
+
+ // this value slowly decreases from 1 to 0 when we stop touching the ground.
+ // The cycle is later multiplied with it so the view smooths back to normal
+ if (clonground && !clcmdjump) // also block the effect while the jump button is pressed, to avoid twitches when bunny-hopping
+ cl.bob2_smooth = 1;
+ else
+ {
+ if(cl.bob2_smooth > 0)
+ cl.bob2_smooth -= bound(0, cl_bob2smooth.value, 1);