float lastclientthink, sv_maxspeed, sv_friction, sv_accelerate, sv_stopspeed, sv_edgefriction; .vector movement; float(float a, float b) min = #94; // returns the lesser of the two numbers (only faster than if else in rare // cases - if you would have to set two variables, then decide, use this // instead, otherwise stick with the if/else block for speed) void() SV_PlayerPhysics = { local vector wishvel, wishdir, v; local float wishspeed, f; if (self.movetype == MOVETYPE_NONE) return; if (self.punchangle != '0 0 0') { f = vlen(self.punchangle) - 10 * frametime; if (f > 0) self.punchangle = normalize(self.punchangle) * f; else self.punchangle = '0 0 0'; } // if dead, behave differently if (self.health <= 0) return; // show 1/3 the pitch angle and all the roll angle // LordHavoc: no real interest in porting V_CalcRoll //self.angles_z = V_CalcRoll (self.angles, self.velocity)*4; self.angles_z = 0; if (!self.fixangle) { // LordHavoc: pitch was ugly to begin with... removed except in water if (self.waterlevel >= 2) self.angles_x = (self.v_angle_x + self.punchangle_x) * -0.333; else self.angles_x = 0; self.angles_y = self.v_angle_y + self.punchangle_y; } if (self.flags & FL_WATERJUMP) { self.velocity_x = self.movedir_x; self.velocity_y = self.movedir_y; if (time > self.teleport_time || self.waterlevel == 0) { self.flags = self.flags - (self.flags & FL_WATERJUMP); self.teleport_time = 0; } return; } if ((self.movetype != MOVETYPE_WALK) || (self.flags & FL_ONLADDER) || (self.waterlevel >= 2)) makevectors(self.v_angle); else // Kryten: dont want to slow down if you look down while walking makevectors(self.angles); if (time != lastclientthink) { lastclientthink = time; sv_maxspeed = cvar("sv_maxspeed"); sv_friction = cvar("sv_friction"); sv_accelerate = cvar("sv_accelerate"); sv_stopspeed = cvar("sv_stopspeed"); sv_edgefriction = cvar("sv_edgefriction"); } // swim if (self.waterlevel >= 2) if (self.movetype != MOVETYPE_NOCLIP) { if (self.movement == '0 0 0') wishvel = '0 0 -60'; // drift towards bottom else wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z; wishspeed = vlen(wishvel); if (wishspeed > sv_maxspeed) wishspeed = sv_maxspeed * 0.7; else wishspeed = wishspeed * 0.7; // water friction if (self.velocity != '0 0 0') { f = vlen(self.velocity) * (1 - frametime * sv_friction); if (f > 0) self.velocity = normalize(self.velocity) * f; else self.velocity = '0 0 0'; } else f = 0; // water acceleration if (wishspeed <= f) return; f = min(wishspeed - f, sv_accelerate * wishspeed * frametime); self.velocity = self.velocity + normalize(wishvel) * f; if (self.flags & FL_WATERHACK) self.velocity_x = self.velocity_x + 0.0001; return; } // hack to not let you back into teleporter if (time < self.teleport_time && self.movement_x < 0) wishvel = v_right * self.movement_y; else wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z; // Kryten: look up + move forward = move up, but not if using +moveup and +movedown if ((self.movetype != MOVETYPE_WALK) && self.movement_z) wishvel_z = self.movement_z; else if (self.flags & FL_ONLADDER) wishvel_z = (wishvel_z + (v_forward_x * self.movement_x)) / 2; else if (self.movetype == MOVETYPE_WALK) wishvel_z = 0; wishdir = normalize(wishvel); wishspeed = vlen(wishvel); if (wishspeed > sv_maxspeed) wishspeed = sv_maxspeed; // Kryten: look up + move forward = move up; i like it that way if ((self.movetype != MOVETYPE_WALK) || (self.flags & FL_ONLADDER)) self.velocity = wishdir * wishspeed; else if (self.flags & FL_ONGROUND) // walking { // friction if (self.velocity_x || self.velocity_y) { self.velocity_z = 0; f = vlen(self.velocity); // if the leading edge is over a dropoff, increase friction v = self.origin + self.velocity * (0.0625 / f) + '0 0 1' * self.mins_z; traceline(v, v + '0 0 -34', TRUE, self); // apply friction if (trace_fraction == 1.0) { if (f < sv_stopspeed) f = 1 - frametime * (sv_stopspeed / f) * sv_friction * sv_edgefriction; else f = 1 - frametime * sv_friction * sv_edgefriction; } else { if (f < sv_stopspeed) f = 1 - frametime * (sv_stopspeed / f) * sv_friction; else f = 1 - frametime * sv_friction; } if (f < 0) self.velocity = '0 0 0'; else self.velocity = self.velocity * f; } // acceleration f = wishspeed - (self.velocity * wishdir); if (f > 0) self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed); } else // airborn { if (wishspeed < 30) f = wishspeed - (self.velocity * wishdir); else f = 30 - (self.velocity * wishdir); if (f > 0) self.velocity = self.velocity + wishdir * (min(f, sv_accelerate) * wishspeed * frametime); } if (self.velocity) { // Kryten: remove flag in case leaving self.gravity = 0; self.flags = self.flags - (self.flags & FL_ONLADDER); self.flags = self.flags - (self.flags & FL_WATERHACK); } }